morygonzalez
fringe worker
Posts
自分にとってTwitterでfavする行為、面白いものを見つけてきて☆をつけて遊ぶというか、DJが面白レコード発見してきて人に自慢するのに似た感覚があって、@wyinoue さんとか、箸を転がしただけでも50favされるような人をfavるのは掘ってる感がなくてつまらないと感じる。
-
旧ブログのタグが引き継げていないのでタグを引き継ぐ(なぜか失敗する。DataMapper の挙動怪しい)
-
Production でも SQLite で動いているので変える
- MySQL が妥当なとこだろうけど MongoDB にしてみたら Lokka 用の MongoDB Mapper の開発につながってよさそう。
仕事で勉強したことを趣味グラミングに生かして、趣味グラミングで学んだことを仕事に反映できたらいいと思う。
ポータルシットを AutoPagerizable にしました。
pager のない theme だったら単純に theme をいじって次のページへのリンクに rel="next" とか rel="prev" とかつけて、AutoPagerize させたい HTML エレメントに class=" autopagerize_page_element" とか書くだけで AutoPagerizable になるけど、自分で使ってる theme は yayugu/dm-pagination に依存してるので、プラグインをつくってモンキーパッチした。
こんな感じ。
module Lokka
module AutoPagerize
def self.registered(app); end
end
end
module DataMapper
class Pager
private
def link_to(page, contents=nil, rel={})
%(<a href="#{uri_for(page)}" rel="#{rel[:rel]}">#{contents || page}</a>)
end
def previous_link
li 'previous jump', link_to(previous_page, option(:previous_text), {:rel => "prev"}) if previous_page
end
def next_link
li 'next jump', link_to(next_page, option(:next_text), {:rel => "next"}) if next_page
end
end
end
ついでに LDRizable になるように hentry と hfeed の設定もしといた。
Amazon へのリンクを生成する Lokka Plugin を作りました。テストがないのでまだ単独のリポジトリとしては公開していないけど、以下でコードは取得できます。
lokka/public/plugin/lokka-amazon_associate at portalshit · morygonzalez/lokka
Update 2012-04-15
いつまで経っても全部テスト書けそうにないのでテストほぼないけどとりあえず単独のリポジトリとして公開しました。
morygonzalez/lokka-amazon_associate
使い方ですが、プラグインを LOKKA_ROOT/public/plugin/ に入れた後、ブラウザで www.example.com/admin/plugins/amazon_associate にアクセスしてご自身の Associate Tag と Access Key ID と Secret Key を入れます。
お使いの Lokka の theme を開いて、本文を表示している部分を associate_link() というヘルパーメソッドに渡します。たとえば entry.haml が
.body
= @entry.body
となっているなら、
.body
= associate_link @entry.body
というようにします。
そんで本文中で以下のように書きます。(P_BLOG の頃に使っていた ISBN/ASIN 変換プラグインと同じように使えるようにしました)
<!-- ISBN=PRODUCTID -->
そのうち画像のサイズとか選べるようにしたいですね。
24時間キャッシュするようにしてるけど、 Earthquake.gem で Growl するプラグインの画像をキャッシュするコードを真似てます。
マジで感謝。
youpy さんと negipo さん作の Dropbox を使って私家版 gyazo をやるやつ、便利に使ってたんだけど、Gyazo.app の上に画像ファイルをドロップしてアップロードする機能がなかったので改良した。便利です。
使い方ですが、まずDropbox の Public フォルダ内に gyazo というフォルダを作ります。その後上のファイルをダウンロードしてきて、 /Applications/Gyazo.app/Contents/Resources/script と置き換えてください。ちなみに9行目の
url = 'http://dl.dropbox.com/u/2611378/gyazo/' + File.basename(file)
の ‘2611378’ という数字は僕の Dropbox のユーザー ID なんで、ここはご自分のものに置き換えてください。
Dropbox のユーザー ID は普通に使ってる分には分からないので、以下の手順で調べてください。Dropbox の Public フォルダで適当なファイルを選んで右クリックすると Dropbox メニューがでるので、そこから「パブリックリンクのコピー」を選びます。するとクリップボードに Dropbox のユーザー ID を含んだ URL がコピーされるのでそこから取得してください。
まだ Dropbox のアカウントを持ってない方は以下のリンクから作ってもらえると幸福が実現します。
iPad 買った
会社のタブレット端末購入支援制度を利用して iPad 買いました。この場を借りてお礼申し上げます。ありがとうございます。
iPad には否定的だった
iPad、ずっと年寄りとか情報弱者向けのデバイスだと思って無視してた。小金持ちの情弱サラリーマンとか100万以上カメラにつぎ込んでるカメラじじいが飛びついてる印象しかなかった。とにかく入力がしにくそうで、能動的に情報を取りに行くのではなく、受動的にコンテンツを消費することしかできないような印象があった(文字の入力がしにくいと、情報を検索する頻度が落ちそうだから)。そういうのは新聞や雑誌を読む行為とあまり変わらない。余談だけど新聞社などのオールドメディアが iPad 好きなのと関係ありそう。自分たちが思ったとおりにコンテンツを消費させたいという意志を感じる。
なぜ iPad を買ったのか
技術書を電子書籍で読みたかった
最近、技術書を PDF とか ePub とかで読む行為に興味が出てきて(クソ重い技術書持ち運ぶのに疲れた…)、何冊か PDF 版を買ってみて iPhone で読んでみたら耐えられないくらい読みづらくて何らかのタブレット端末が欲しくなり、 iPad を買ってみたくなった。
デジカメで撮ったばかりの写真を見るのによさそう
あと正月とかにカメラで撮った写真をその場で MacBook に入れて見せると親戚一同が喜ぶので、こういう用途にも向いてるかと思った。Retina ディスプレイだし。
買ってどうだったか
読む端末としては優れている
文章を読む端末としては優れている。Reeder for iPad 入れたら読むのがだるくてたまってたフィードを結構消化できた。(Reeder、Mac 版も iPhone 版も iPad 版も買ってしまった。おすすめです。)
また iPhone では無理だった Twitter に貼られている gist (ソースコードの断片)を見ることが出来て便利だった。iPhone では「後で読む」ものを iPad ではその場で読めるのがいい。
写真きれい
Flickr 見るのが楽しい。写真ブログのフィード、かなり未読がたまってたけど、寝っ転がりながら写真を眺めるのが楽しい。寝床に居ながらにして Flickr にアクセスして友達が撮った写真を眺めて回るのもこれまでにない体験だった。
書きにくい
タッチパネルのフルキーボードだるい。フリック入力したい(* フリック入力できるそうです)。風呂蓋も買ったので斜めに角度つけられるけど、それでも上からのぞき込むようにして文字を入力するのがだるい。
でも革製の風呂蓋はかっこいいのでおすすめです。
iPad Smart Cover(スマートカバー) (Red Cover(革製))
家庭内での共用が難しい
App Store やフォトストリームなど iCloud 系の機能のせいで Apple ID に紐づけられるし、Twitter や Google のサービスを使う際にもログインが必要なのでやっぱり一人一台の方が使いやすい。家族で共用するのは難しいと思う。
総括
Retina ディスプレイやばい
タッチパネルで高精細なのが良い。タッチパネルのタブレットはキーボード操作のパソコンよりも目とディスプレイの距離が近くなるので、Retina ディスプレイとの相性が良いのだと思う(図参照)。「読みたい!」「見たい!」という気持ちにさせられる。正直 iPad 使った後に MacBook 開くと文字がぎざぎざに見えて正視に耐えない。Retina ディスプレイやばい。
持って台所に行けるし寝床に持ち込める
コーヒーいれながら iPhone でなんか読むのが好きなんだけど、これノートパソコンでは絶対できない。両手ふさがるから。iPad だったらぎりぎり片手で持てるので、コーヒーいれながらなんか読むということができる。
あと枕元に気軽に持ち込めるのがよい。ノートパソコンは排気口から埃が入り込みやしないかと心配になってあまり寝るとき使う気にはなれないけど、iPad は気兼ねなく寝床に持ち込める。何か読んでて眠りついたときに枕の横にあっても邪魔にならない。
気軽に持ち運べる点がノートパソコンとの決定的な違いだと思います。
これから望むこと
iPad、おおむね気に入ったけどもっとたくさん日本語の本を読めるようになったらうれしい。文庫本とかを自炊なしで iPad で読めるようになったら最高だと思う。岩波文庫の80年くらい前に出版されたやつをリストカット感覚で買って読んだりしたい(カラマーゾフの兄弟も iPad でなら読めるような気がする)。
あと Retina ディスプレイの破壊力やばいので次の MacBook Pro は Retina で出して欲しいです。
追記
調べたところ、iOS 5 からフリック入力できるらしいです。「iPad は情報弱者向けのデバイス」とのたまってる僕こそ情報弱者でした。お詫びして訂正します。
Lokka になくて不便だと感じていたのがスパムコメントの一括削除機能だった。スパムを取得するメソッド、またそれらをまとめて削除するメソッドはあったので、それを呼び出すインターフェースを作ってみた。最初はテストなしで pull request しようとしてたけど Lokka に怒濤のようにテストコードを書いて push している tomykaira さんのブログ記事(lokka コミッタからのお願いをお読みください - tomykaira makes love with codes)を読んで心を入れ替え、本日の Lokkathon でテストコードを書いて pull request してみた。無事 merge して頂きました。
Commit ebd152916587ffd67680d4c034b8ce17956c414c to komagata/lokka - GitHub
P_BLOG の改造とかして地道にコードを公開したりはしてたけど、やっとオープンソースにコミットできた感じがする。もっと頑張っていきたいです。
いまの会社は労働環境よいんだけど、前働いていた会社がとてもつらかった。どのくらいつらかったかというと、もう辞めてしばらく経つのに、いまだに前の会社にいたころの夢を見てうなされて夜中に目が覚めるくらいつらかった。ある意味トラウマになってしまっている。
つらかった頃のことをここに書いても意味がないことは分かっているし、ネガティブな感情をインターネット上に発露するのは個人的な信条に反するんだけど、セルフヒーリングのために前勤めていた会社のことを書いてみる。
無限サービス残業
- 22時に帰るときも日報に「本日私用のためお先に失礼します」と書かなきゃいけない雰囲気だった。
- 「23時に佐川が来るので申し訳ありませんがお先に失礼します」と日報に書いてる女の子とかいた。
- 社長が「震災のおかげで仕事が減って早く帰れてうれしい、とか言ってるやつは許さない」とか言ってた。
- みんなサービス残業してるので会社の飲み会に開始時間通りに現れる人はほとんどいなかった。
- 週末だからと会社のメンバーで飲みに行くなんてことはなく、金曜の夜は2時くらいまで仕事するのが普通だった。
前の会社でまずつらかったのが労働時間の長さだった。もちろん残業代は出ない。完全に違法なんだけど、雇用主と労働者が対立する時代は終わったとか、不満があるなら辞めろとかいうような内容のメールを総務担当者が月に一回くらい送ってよこしていた。自分は弱いから会社に待遇を改善するよう申し出ることなんてできず、短期間働いて辞めることであの環境から脱した。
軍隊っぽさ
- 上長にメールを送るときには宛名に「様」とつけなければならなかった。
- 毎晩2時まで働いてたせいで心身を病んだ人が二人いたけど、二人とも「体調管理は自己責任」といって休職中に辞めさせられてた。ちなみに休職中に辞めさせるのは労働基準法違反らしい。
- 細かく職位が分かれていて社内に軍隊のような階級制度があった。職位によって届くメールやグループウェア上で閲覧することのできるファイルが細かく分かれていた。たとえば上長の書いた日報は部下は読むことができなかった。
全体的に戦時中の日本みたいな会社だった(「欲しがりません 勝つまでは」的な感じ)。ライバルに勝つため・家族を守るために自分を犠牲にしろとか、そんな感じのことを経営陣が言ってた。
職位ごとに権限が異なっていて閲覧可能なファイルに違いがあるのはよその会社でも普通にやってると思うけど、それが露骨かつ過剰に行われている感じだった。Active Directory が Windows Server の外にもやってきて従業員をコントロールしている感じだった。
離職率の高さ
- 入社してから二ヶ月以内に辞める人が多かった。いわゆるバックレも多かった。
- 入社一年も経ってないのに入社時期で降順ソートしたとき真ん中くらいになってた。
自分の歓迎会開いてもらったときにすでに入社してから半年経ってた。すぐ辞める人が多いので新人の歓迎会とかはなかなか開いてもらえない。なんか先月入った人最近見かけないなー、と思ったらいつの間にか辞めてたということが日常茶飯事だった。
待遇の悪さ
- 試用期間の二ヶ月間は各種保険に加入させてもらえなかった。
- 内定の時に伝えられた年俸と全然違う給料だった。
全体的に、社長に気に入られないと昇級も出世も望めなかった。まぁどこの会社でも多かれ少なかれそうなのかもしれないけど、給与の等級表とかなかったし、どうすればどのくらいの給料をもらえるというような明確な指標がなかった。
労働基準監督署に届けてある就業規則はあるにはあったけど、偉い人の机の前にあって簡単に読める雰囲気じゃなかったし、そんなことしてる暇あったら仕事しろと注意される感じだった。ボーナスが支払われるのはいつか、基準額はいくらなのか、など労働契約に関する諸々のことを知らされない状態で働いていた。
技術力よりも人間力
- 技術について熱っぽく語るとめんどくさいやつみたいな扱いを受けた。
- 出世するにはエンジニアをやめてプロジェクトマネージャーにならないといけなかった。
- テストコードとかなかった。テストは全部手動だった。
- 勤務時間のうちコード書いてたのは25%くらい。あとは全部ドキュメント作成だった。
これらの開発カルチャーに加えて、会社が依拠する技術が Microsoft や Adobe などプロプライエタリなものが中心であり、UNIX/Linux 系の開発が好きな自分には大変つらかった。Capistrano とか使えば20秒くらいで終わりそうなことを手動・目視確認で行っていて、技術面のアナクロニズムに耐えられなかった。
インターネットのことを好きな人がいなかったのも辛かった。はてなとか誰も見てなかったし、 Twitter アカウントはみんな隠してた。そもそも Twitter よりも Facebook な感じだった。ソーシャルネットワークはプロモーションのツールとしてしか認知されていなかった。Twitter なんて技術的には大したことない、が社長の口癖だった。エンジニアも誰も GitHub とか使ってなかった。
不用意に転職したのが間違いだった
一番の間違いは、Web制作の会社に入ってしまったことだと思う。Twitter で見かける楽しそうに仕事してる人たちはだいたいみんなWeb系のベンチャー企業とかで働いてた。制作会社とWeb系ベンチャーでは全然雰囲気が違うと思う。制作会社にはクライアントがあり、その人たちの言うことは絶対だから、アホみたいなリクエストにも全力で答えなければならない。
Aという企業があってその会社のユーザーのためのサイトをWeb制作会社が作っているとする。すると要求の流れが以下のようになる。
A社製品のユーザー -> A社(顧客) -> 営業担当 -> プロジェクトマネージャー -> エンジニア・デザイナー
エンジニア・デザイナーはこのサイトの制作に携わるプレーヤーの中で最下層にある。顧客の要望を営業担当が聞いてきて、それをプロジェクトマネージャーが伝え聞き、エンジニアとデザイナーに指示を出す。このメカニズムのなかで軍隊的な階級構造ができる上がるのではないかと感じる。良くない仕組みだと思う。
近況
前の会社には一年近くいたけど、何か身についたかと問われると何も身についてない。自分の人生の中で最低最悪の暗黒時代だった。がんで入院していた頃の方がまだ良かったような感じさえする。
この記事のような愚痴というか後悔の塊みたいな文章をネットにのっけても何の得にもならないんだけど、職探しは本当に真剣にやった方がいいと身をもって思った。確かに結局のところ会社に入るまでその会社が自分に合っているのかどうかはわからない。しかしだからといって適当に就職活動して就職するとものすごく後悔することになる。時間がかかってもいいから就職・転職先はじっくり見極めてから決めた方がいいと思う。
実は前の会社に入って二ヶ月経たないくらいのときに、入った会社を間違ったと思って転職活動を行った。在福岡の良さそうなベンチャー企業を見つけたので面接を受けに行った。技術的には面白そうなことやってそうだったが、外に向かって社内のことを明らかにしていない会社で、中のことが全然わからなかった。なので結局内定を辞退した。面白そうだけど社員のブログやTwitterが読めないとなるとものすごく不安になる。
ペパボに入ったのは、アラタナ研究所所長の rytich さんのかつての職場で、rytich さんに声かけてもらってペパボの人と一回酒飲んだことあったし、かぶりものの社長とか創業者の家入さんとか何となく知ってて安心感があったから。とはいえどんなことやってるかよくわかんなくて不安がないわけじゃなかった。そういうよくわかんなさを吹き飛ばしてくれたのは刺身☆ブーメランさんのブログだった。
あるウェブアプリケーションプログラマの一日 ~ ペパボ・ 30days Album 編 - 刺身☆ブーメランのはてなダイアリー
これ読んで「あ、なんか大丈夫そう」と思ったから面接受けに行った。
刺身さんにはペパボに入ってからもRailsのこととか教えてもらって世話になってるけど、あの記事読まなかったらペパボ受けようと思わなかったかもしれないと思うと何とも言いようのない感謝の念がわいてくる。ありがとうございます。もちろん rytich さんも、もうペパボ退職されたけど taketin さんもありがとうございます。
雑然とした感じの日記になったけど、自分はいま楽しく働いてます。
プログラマならUS配列でしょ、と思って最近買ったHHK ProとMacBook AirはUS配列を選んだけど、使いにくくて非常にストレスを感じている。プログラマは全員英語環境でパソコン使うべきってのは妄言だと思った。JISに慣れてたらJISの方がいい。
個人的に耐えられない点を以下に列挙。
1. 英数 <-> かな切換の煩わしさ
自分の場合、英数 <-> かなの切換をキーを一個押すだけでできないのには多大なストレスを覚える。コマンド + スペースで切り換えられるとはいっても、いま英数・かなどちらの入力モードにいようとも英数文字を入力したければ英数キーを叩いてから入力すれば必ず英数文字を入力でき、逆の場合も確実にかな文字が入力できるJIS配列キーボードの方が便利だ。
2. MacBook AirのUSキーボードのtildeキーの位置
なんと狂っていることに、”~” (tildeキー)が左上エスケープキーの下部分にある。JIS配列でいうところの「1」のとこらへんだ。なんだってこんなところにtildeを用意するのだろう。tildeはシェルで自分のホームディレクトリを表す記号で大変よく使うキーだ。アメリカ人は不便に感じないのだろうか。
3. returnキーの小ささ
JISキーボードのreturnキーは大きく、大変打ちやすい。しかしUS配列ではreturnキーは小振りになり、右shihtキーの上に同じ程度の横幅で慎ましやかに座している。こんなの超打ちにくい。しかもreturnキーのすぐ上にdeleteキーがあるものだから、JISキーボードの癖でreturnしようとしてdeleteしてしまうことがしばしばあるのだ。非常にうざい。
4. コロン入力時にshihtキーがいる
僕のメインテキストエディタはVimなんだけど、Vimではコマンド入力時に “:” (コロン)を多用する。JIS配列ではコロンは単独キーで入力できるが、US配列ではセミコロンとコロンが同じキーに割り当てられており、shihtキーを押しながらセミコロンを押すことで入力できる。Vimでガリガリコードを書いているときに非常に煩わしい。Vimでコード書くときの時間が1.5倍くらいになってるような気がする。
以上、自分にとって英語配列キーボードのいけてない点をつらつらと書いてきた。KeyRemap4MacBookとかでキーマッピングをカスタマイズしてから使えやハゲ、とかいわれそうだけど、非純正のソフトに依存しないとキー入力すらままならなくのは嫌なので自分はそんなん導入したくない。
結局、JIS配列に慣れ親しんだ人間がUS配列のキーボードに切り替えるメリットは少ないように思う。キートップからひらがなが消えてシャレオツになるくらいか。アメリカに転勤することになって今後は現地のUSキーボードのパソコンしか買えなくなってしまった、とかであればUS配列への鞍替えは避けられないと思うけど、そうでない場合は無理してUS配列のキーボードを使う必要なし。
Posts
I know why you came here. BECAUSE IT’S HARD TO FIND CONTENT IN GITHUB WIKI!!!
Here is a solution.
My colleague Tomohisa created a nice userscript. It provides you an ability to search GitHub Wiki in pretty easy way.
Install the script from his GitHub repository. It’s compatible with Firefox (with Greasemonkey, of course), Google Chrome and Safari (with Nijakit).
github-wiki-search/github-wiki-search.user.js at master · linyows/github-wiki-search · GitHub
Then you will find search box on right above “Page History” button.
Now search all the wiki content with github-wiki-search.user.js!
Mac の iTerm 2 皆さん使ってますか。コンソール中に現れた文字列をハイライト通知できたりしていろいろ便利らしいですね。でも僕は使っていませんでした。なぜか。
Ctrl + Shift + J によるかな入力変換ができないから。
これが非常にだるかった。宗教上の理由や国外在住でJISキーボードが手に入らないなどの理由のためやむなく英語キーボードを使っている方、おられると思います。そういう人はだいたい Ctrl + Shift + J で英数 -> かなの入力変換を行っていると思いますが(Command + Space の切り換えもできなくはないけどだるいですよね…)、iTerm 上では Ctrl + Shift + J で改行が行われてしまうため、このような操作が行えていませんでした。かなから英数入力に切り替える Ctrl + Shift + * も同様、むなしく ' などが表示されるだけ。標準の Terminal.app ではできるのになんでやねん。
iTermでの日本語入力 - 初学者の箸置 なんかを参考に Send Hex Codes 0x4a するようにしてみたりしたのだけどうまくいかなかった。
しかし先ほど仕事をさぼって iTerm の設定項目を確認していたら以下の設定で使えるようになったのでここに書き記しておきます。
↑のように、iTerm の Preferences -> Profile -> Keys で Ctrl + Shift + J、 Ctrl + Shift + * の項目を追加し、メニューから “Do Not Remap Modifiers” を選ぶだけでオッケー。かな英数の切り換えが快適に行えるようになる。困っている方お試し下さい。
Railsで画面を作っていて、DBを参照せずにselect -> option なHTML(ドロップダウンリスト)を出力したいと思った。DBに入ってない値をドロップダウンリストとして表示する方法。ググったらこういうやり方がヒットした。
dropdownlist - Rails non-table drop down list - Stack Overflow
このやりが方がかっちょいいのかバッドノウハウなのか判別つかないけど、モデルに定数を書いてそこにいろいろ入れてしまうらしい。以下のような感じ。
class Event < ActiveRecord::Base
DAYS = ['Monday', 'Tuesday', 'Wednesday', ...]
end
でこれをモデルから参照するときは以下のようにする。
<%= select(:event, :day, Event::DAYS) %>
これでうまいことドロップダウンリストを表示できる。
ところが一点問題があって、このドロップダウンリストで表示したい値が "(ダブルクオーテーション)を含んでいたとする。ダブルクオーテーションはRailsによって自動的にエスケープ処理されてしまうので、 " と表示させたいのに " とか表示されてしまう。Form系のヘルパーメソッドで text_area_tag なら :escape => false とか出来るんだけど、select でそれをやるのは不可能だった。
Railsで文字列のエスケープをせずに出力する方法は一般的に
<%= raw("文字列") %>
とか
<%= "文字列".html_safe %>
だけど、「まさかそれをモデルの中でやっちゃってもエラー出るよね?」と思いながらやってみたらちゃんとエスケープせずにHTMLを出力できた。
モデルクラスのなかにヘルパーメソッドを書くのは気持ち悪いと思うけど、それ以外ではビューの中でイテレータを書いて一個一個エスケープしない処理を書くか、独自のヘルパーメソッドを書くしかない。なんかまどろっこしい気がするのでとりあえずこのやり方で行ってみることにします。
2011年はてなインターンであらせられるuasiさんのはてなブログに解決方法が書いてありました。
Tmux で pbcopy/pbpaste が効かないやつ - uasi:ウアシー
MacVimが悪いんじゃなくてtmuxに原因があったみたい。tmuxごしにVimを起動すると、MacVimでなくて普通のVimでもコピペができなくなる不具合があったようです。しかしChrisJohnsen/tmux-MacOSX-pasteboard - GitHubをインストールすることで解決します。tmuxだけでなくGNU Screen + Vimの組み合わせでも同様の問題が解決するそうです。お困りの方はお試し下さい。
Railsで建物名みたいなカラムに building ってのを当ててたら
ActionView::Template::Error (no block given (yield)):
みたいなエラーが出るんですけど、Railsで building って予約語なんですかね。
なんか Rails Wiki のReserved Words You Can’t Use は真っ白だし、古い方のWikiの予約語一覧 にも building は入ってないし。
とりあえず複数形にして対応したけど気持ち悪い。
追記
どうやらMongoidに起因するエラーのようです。
RVM、便利に使わせてもらっていたけど、Rubyの新しいのがリリースされるたびにいろいろアレだったので rbenv を使ってみることにした。移行、しんどいかなと思ってたけど非常に簡単で大変よかった。
RVMもキモさ
RVMの悪いところはググればいろいろ出てくるけど、OSの cd やRubyの gem コマンドをシェルスクリプトで置き換えるとか、行儀が悪いところが問題らしい。個人的に気にくわなかったのがRVMがどんどんでかくなっていって、Rubyのビルドに必要なパッケージまで管理できるようになったところとか(.rvm以下に新しくシステムができるみたいな感じがキモかった)、パッケージインストール用のコマンドがhelpドキュメントでは rvm package install なのに rvm pkg install にいつの間にか変わっていて訳がわからないところとか、よくわからないシェルスクリプトがログイン時に実行されるところとか、 rvmsudo っていうコマンドのキモさとかいろいろ。
rbenv
rbenvはRubyのバージョンを切り替えるためのツールなのでインストールはやってくれないけど、ruby-buildというツールを別に入れることで、 rbenv install 1.9.2-p290 とかでRubyのインストールもこなしてくれるようになる。
あまりRVMを使いこなしてたとはいえなかった自分にとってはrbenvくらいでちょうどいいような感じがする。gemsetとか使わんし。そんくらいだったBundler使うし。
インストールは以下のページが参考になります。
rbenv + ruby-buildのインストール方法 - 223 Software
なおrbenvはRubyインストール時のconfigureオプションの指定方法が特殊です。直接は指定できないようなので以下のようにします。(homebrewでインストールしたreadlineとiconvのパスを指定する例)
$CONFIGURE_OPTS="--with-readline-dir=/usr/local --with-iconv-dir=/usr/local" rbenv install 1.9.2-p290
デフォルトのオプションなしのRubyだとearthquake.gemが動かなかったりjekyllが使えなかったりするので僕は↑のオプションを追加しました。よろしかったらお試し下さい。
LokkaをCMSに採用している ポータルシット はHerokuで動かしてたんだけど、Lokkaをカスタマイズして使っているためか、デプロイしてもApplication Errorばかり出るようになってしまった。ローカルのMacではうまくいくのに。一週間くらい直そうと努力してみたけど直りそうにないのでHerokuでの運用を諦めてさくらVPS上のUbuntuで運用することにした。すこぶる快適。
Herokuは確かに便利なんだけど、Herokuの中でどういう風にアプリケーションが動いているのかを把握しづらい。ファイルシステムに直接アクセスできないので、ログを見るにも heroku logs とかやんないといけない。
その点、自分で環境をいじれるサーバーだったらウェブアプリケーションのログはおろかシステムログまで見られるし、無理にHerokuで運用してHerokuで運用するために時間を割くのは馬鹿らしいような気がする。
Amazonの検索結果画面で、個別商品URLへのリンクが target="_blank" 指定となっていてうざかったので target="_self" と置き換えるユーザースクリプトを書いた。
地味に便利。
Ruby 1.9.2-p290 がリリースされたので入れてみた。RVMで。
rvm install 1.9.2 --with-readline-dir=/usr/local #homebrewで入れたreadlineのパスを指定
rvm migrate ruby-1.9.2-p180 ruby-1.9.2-p290
migrate を実行したところ、警告が出ながらも次のような感じでマイグレーションは完了した。
rvm migrate ruby-1.9.2-p180 ruby-1.9.2-p290
Are you sure you wish to MOVE gems from ruby-1.9.2-p180 to ruby-1.9.2-p290?
This will overwrite existing gems in ruby-1.9.2-p290 and remove them from ruby-1.9.2-p180 (Y/n): Y
Moving gemsets...
Moving ruby-1.9.2-p180 to ruby-1.9.2-p290
Making gemset ruby-1.9.2-p290 pristine.
ERROR: Error running 'rvm gemset pristine' under ,
please read /usr/local/rvm/log//gemset.pristine.log
Moving ruby-1.9.2-p180@global to ruby-1.9.2-p290@global
Making gemset ruby-1.9.2-p290@global pristine.
ERROR: Error running 'rvm gemset pristine' under ,
please read /usr/local/rvm/log//gemset.pristine.log
Do you wish to move over aliases? (Y/n): Y
Do you wish to move over wrappers? (Y/n): Y
Do you also wish to completely remove ruby-1.9.2-p180 (inc. archive)? (Y/n): Y
Successfully migrated ruby-1.9.2-p180 to ruby-1.9.2-p290
一見、問題なく移行できたように思えるのだけど、この後rakeなどexecutableなgemをコマンドラインから実行すると以下のようなエラーが出る。
zsh: /usr/local/rvm/gems/ruby-1.9.2-p290/bin/rake: bad interpreter: /usr/local/rvm/rubies/ruby-1.9.2-p180/bin/ruby: no such file or directory
rake aborted!
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)
/usr/local/rvm/gems/ruby-1.9.2-p290/gems/rake-0.8.7/lib/rake.rb:2377:in `raw_load_rakefile'
(See full trace by running task with --trace)
shebangに書いてあるrubyのパスがmigrate時に削除した ruby-1.9.2-p180 なのが問題なわけだ。
正しい対処方法かどうかは自信がないが、Rubyでサクサクッとshebangを書き換えるやつを書いた。以下みたいなやつ。
こいつを実行してやるとshebangが正しく書き換わったexecutableなgemができる。万が一のためにbackupファイルを作るのでこれをzshで rm *_backup とかしてやるといいと思います。
と思ったけど、結局↑のRubyの入れ方はまずいみたいで、jekyllとかCライブラリに依存する系のgemが動かなくなってしまったので rvm implode してRVMをまるっと入れ替えた(20回くらいRubyをインストールしなおした)。次の記事にでも書きます…。
JekyllはLiquidというRubyのテンプレートエンジンを採用してるんですが、Liquid内でLiquidの文法をエスケープする方法が分からず大変苦しんでおりました。Jekyllの公式のDocument呼んでもXML出力時とかCGI出力時にコンテンツをエスケープする方法は書いてあるのに、Liquidテンプレート自体をエスケープする方法が書いてなく、大変不満でした。しかしその方法が分かったのでお知らせいたします。元ネタはスタックオーバーフロー。
web development - How to escape liquid template tags? - Stack Overflow
例えば {% this } と表示させたかったらこうやります。
{{ "{% this " %}}}}
ちょっとトリッキーですね。
Pygmentsと組み合わせて使うことも可能ですが、いちいち {% highlight } のなかでコメントアウト処理をしてあげないといけないません。面倒くさいですね。
Jekyllを使いだしてから気がつくと一年経ってました。いろいろ便利に使えており気に入っております。
PygmentでコードをシンタックスハイライトしたりLSIで関連記事表示したりと結構手を入れてはいたんだけど、いわゆる世間の一般のブログにあるようなカテゴリ一覧表示機能と、カテゴリごとの記事アーカイブ機能がなくて、それを若干不便に思っておりました。
ググってみたところ、プログラマー向けなブログツールなだけあっていろんな方法が出てきました。以下そのまとめ。
カテゴリ一覧
JekyllのLiquid (テンプレート言語) には {{ sites.categories }} みたいタグがあるんだけど、こいつが意図したとおりに動かない。普通のRuby使いの感覚からすると site.categories ってカテゴリを沢山持った配列になってそうな気がするんだけどこれが違う。
1 <ul>
2 {{ for category in sites.categories }}
3 <li>{{ category.name }}</li>
4 {{ endfor }}
5 </ul>
↑みたいな感じのコード書くと何も表示されない。 site.categoires はHashで、{ "カテゴリ名" => カテゴリ内の記事一覧 } みたいな構造になってる。LiquidでHashのキーを取りだす方法が分からず、どうにもこうにもいかなかったので他の人が作っているプラグインを利用することにした。
tag_category_iterator/tag_category_iterator.rb at master from rfelix/my_jekyll_extensions - GitHub
↑のファイルを JEKYLL_ROOT/_plugins にコピーする。(_plugins というディレクトリがなければ作る)。そんでテンプレートを変更する。↑のやつを↓みたいにする。
1 <ul>
2 {{ for category in sites.iterable.categories }}
3 <li>{{ category.name }}</li>
4 {{ endfor }}
5 </ul>
2行目のところが変更点です。これでカテゴリ一覧表示ができるようになる。
カテゴリごとの記事一覧
カテゴリごとの記事一覧を表示する方法だけど、こういうのを発見した。
Jekyll Plugins - Recursive Design
ここの generate_categories.rb を使えばカテゴリ内の記事一覧を作成できる。こんな感じ。
Category: Ruby | tech.portalshit.net
これもさっきのと同じように、JEKYLL_ROOT/_plugins にファイルをコピーする。そんでLiquidテンプレートを書き換えるんだけど詳細はプラグイン内の記事をご確認くだしあ。
暇だったので自動で特定のユーザーを延々favし続けるスクリプトを書いた。
ヒトデ君が書いた hitode909/user-stream-receiver - GitHub とRuby+User Stream APIで無言リプライに高速返信するbotを作りました - ps aux | grep aquarla を参考にさせてもらった。というかほとんどまるパクリ。またOAuthのところはtily氏の tily/ruby-oauth-cli-twitter - GitHub に全面的に依存している。
User Stremを受診してるのでcronとかの設定なしでネットストーキングしたい相手のことを延々追跡できる。しかも発言があった瞬間に即favする。大変気持ち悪いですね。
しかしUser Streamはときどき調子が悪く、発言を拾い落とすこともある。そんなときは以下のコードを使う。
これでUser Stream経由で取りこぼした発言もfavできる。それぞれ使い方はこんな感じ。
ruby favoritter.rb ストーキングしたい相手のユーザー名
ruby favstream.rb ストーキングしたい相手のユーザー名
二月末に行ったスマートフォン開発環境セミナー(仮)でmasuidriveさんのTitanium Mobileについての発表を見てすっかり感化された。これからはJavaScriptで空を飛べる時代が来ると思った。
ドイツの会社がやってるToDo管理のサービスにWunderlistってのがあって、これは結構かっちょいUIのiPhone/Mac/PC/Webアプリを出してたりする。なんでそんなにマルチプラットフォーム対応できんの? と思ってたらどうもTitanium MobileとTitanium Desktopを使ってるみたい。だから簡単にマルチプラットフォーム対応できてるわけ。他にもThe Hit Listが一向にiPhoneアプリを出さないのでそれに業を煮やしたSenchaの社員が作ったHub ListっていうアプリもJavaScriptでデスクトップアプリを書いててマルチプラットフォーム対応してる。
しかし、なんかTitanium Desktop使って僕みたいなスキルしょぼい人がアプリ作るときじゃくせい(なぜか変換できない)を突かれて困ったことになる懸念もあるみたい。
Titanium Desktop 雑感。 - TokuLog 改メ tokuhirom’s blog
とはいえ、最近プログラム書き始めたばっかでObjective-CとかJavaとか分かんない自分には、JavaScriptでiPhone/Androidはもちろんのこと、MacやWindows、はてはLinux向けのデスクトップアプリケーションが作れてしまうのTitanium MobileとTitanium Desktopにはとてつもない魅力を感じる。
連休期間中にしょぼいのでいいからなんか一個作りたい。
MacVimでコピペできなくて(MacVim内のヤンクじゃなくて、他のアプリケーションでコピーしたもののペースト)困ってたんだけど(MacVimでコピペできないんですけど… | tech.portalshit.net)、できるようになりました。原因は mvim っていう、コマンドラインからMacVimを起動するためのシェルスクリプトだった。MacVim kaoriyaのWikiで紹介されてるやつ。
こいつ経由でMacVimを起動したときはどうも他のアプリケーションからのコピペがうまくいかないみたい。
同じくMacVim Kaoriya Wikiで紹介されている、MacVimを起動するコマンドをaliasで化したものを .zshrc に書いたところうまくコピペが機能した。
alias gvim='env LANG=ja_JP.UTF-8 open -a /Applications/MacVim.app "$@"'
同じ問題でお困りの方はお試しあれ。
追記
なんか違うっぽい。alias経由で呼び出してもダメなときはダメだもん。いったい何なんすかね。
ポータルシットをLokkaに置き換えたくていろいろやってる。ポータルシットの過去記事をYAMLでエクスポートし、それをLokkaのDBに取り込む作業をやってる。TDD BootCampに参加したので、テストファーストしながらの作業。RSpecでテストコードを書き、ログが正しくインポートできることを確認する。テスト終了時 after(:all) フックで、取り込んだログを削除してる。コードはこんな感じ。ちなみにLokkaはDataMapperをORMに採用してるので以下はDataMapperでの話。
after(:all) do
Category.all.destroy
Entry.all.destroy
end
しかしこれでは AUTO INCREMENT の値がリセットされず、テストを繰り返す度に AUTO INCREMENT の値が増えていってうざかった。
DataMapperの機能で AUTO INCREMENT 値をリセットするのってないのかなと5秒くらい探してみたけど見つからなかったので、SQLを直接実行する方法を採用した。
ちなみにRDBMSに採用してるのはSQLite3。SQLiteでは UPDTE sqlite_sequence SET seq=0 WHERE name='テーブル名'; みたいなコードで AUTO INCREMENT 値を任意の値に設定できるみたい。
最終的な after(:all) フックはこんな感じ。
after(:all) do
Category.all.destroy
Entry.all.destroy
Entry.repository.adapter.execute('update sqlite_sequence set seq=0 where name="entries";')
end
テスト実行後にはすべてのデータがデータベースから削除されて、AUTO INCREMENT の値もリセットされる。人畜無害なテストコード万歳。
MacVimでコピペできないのって仕様?
MacVimに他のアプリケーションでコピーしたものを貼り付けられないのって仕様? いろいろ調べてみたけどストライクな解決方法はないみたい。結局CLIのVim使ってる。
関連記事表示
Jekyllで関連記事を表示するようにした。jekyllを実行するときに jekyll --lsi とするんだけど、Classifierというgemが必要。ただしClassifierを入れてるだけだと似てる記事を探すのにすんごい時間がかかるので、gslというgemを入れる。しかしこれはただ単に gem install gsl しただけでは以下のようなエラーが出る。
Fetching: narray-0.5.9.9.gem (100%)
Building native extensions. This could take a while...
Fetching: gsl-1.14.7.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing gsl:
ERROR: Failed to build gem native extension.
/Users/morygonzalez/.rvm/rubies/ruby-1.9.2-p136/bin/ruby extconf.rb
checking gsl version... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/Users/morygonzalez/.rvm/rubies/ruby-1.9.2-p136/bin/ruby
extconf.rb:237:in `rescue in <main>': Check GSL>=0.9.4 is installed, and the command "gsl-config" is in search path. (RuntimeError)
from extconf.rb:138:in `<main>'
GSL(GNU Scientific Library)が入ってないのがダメらしい。Homebrewでインストールする。
$ brew install gsl
そんでもう一回 gem install gsl するとうまく入った。 _config.yaml に lsi: true という記述を追記して jekyll を実行すると関連記事が表示されるようになった。
最近の記事表示
ついでに見た目を調整した。サイドバーに全部の記事が表示されてたのがうざかったので10件だけ表示するようにした。
8c72..2c84ea5 100644
--- a/_layouts/post.html
+++ b/_layouts/post.html
7 +69,7 @@
<h3>Latest Posts</h3>
<ul>
- {`% for post in site.posts `%}
+ {`% for post in site.posts limit:10 `%}
<li><a href=""></a></li>
{`% endfor `%}
</ul>
(↑Liquidでエスケープする方法がわからんかったので {`% とかなってますけど、正しくは {% です)
Liquidでは配列に対して {% for post in site.posts limit:10 %} という書き方をすることでループ処理の回数をコントロールできるみたい。
全体的に見やすくなりすっきりした。
確認ダイアログを出しながらディレクトリやファイルを削除するスクリプトを書いた。大したコード書いてないし逆引きRubyに載ってたコードをまるパクリしてるところもあるけど便利だと思う。
そのディレクトリにあるファイル/ディレクトリ一覧を取得した後、「このファイル/ディレクトリは作られてから何日経っています。削除しますか? (y/n)」というダイアログ(英語)を表示する。y が入力されると削除を行う。地味に使える。
RubyのFileUtilsはすごく便利だと思う。シェルスクリプトでしこしこ書くのがアホらしくなる。RubyがPerlなみにあらゆるuni*x系のサーバーに入るようになったらさぞかし便利だろうと思う。
h3 id=vimmabilityVimmabilityのなさ/h3 pTDD Boot Camp福岡で生まれて初めてペアプログラミングを経験した。自分のVimmabilityが思いの外低く焦った。書くの超とろいし、Rubyも全然分かってないしペア組んでもらった人に迷惑かけまくりな感じ。会社では誰もVimとか使ってなくてみんなEclipseとか秀丸使ってるし、周りにVimmerがいないので自分がどんなにしょぼいVim使いなのか気づいてなかった。/p pとりあえず今回、ペアを組んだ a href=http://twitter.com/mallowlabs@mallowlabs/a さんに codecw/code とか codelt;数字gt;y/code とかを教えてもらった。あと/p blockquote pVimでバックスペース使ったら負けだから/p /blockquote pと言われてしまったのでバックスペースと矢印キーをなるべく使わずにプログラム書きたいと思います。でもTextMateとかCodaとか便利だからついつい使ってしまうんよね…。/p h3 id=sectionプログラムが全然書けない/h3 p思ってたよりもプログラムができないことに気がついた。お題を与えられて、制限時間があるなかでコードを書いていかなければならない。しかもペアプログラミングなので一人でちんたら時間をかけて書くわけにもいかない。そしてやっぱ人に見られてると緊張する。Rubyの基本的なメソッドとかが分かってなくて教えてもらいながら書いてたけど、わからないと緊張してしまって頭が真っ白になって何も書けなくなる。いつもリファレンス本を片手にコードを書き捨てていたので、よくないなぁと思った。/p pというか、そもそも自分は仕事であまりコードを書いてないのだ。TDD Boot Campに来てる人たちはみんな公私ともにばりばりコードを書いててとても楽しそうだった。なんだかとても羨ましかった。/p pいろいろ考えないとなー、と思わせられた勉強会だった。/p
pこの前、さくらVPSに入れているUbuntuのzshで codels/code とか codecd/code とか打ったとき、変なエラーメッセージが出るようになった。原因不明。しょうがないのでzshをインストールしなおそうと、codechsh/code してbashとかに切り替えずに codesudo apt-get remove zsh/code してしまった。そこで混乱してしまって codeCtrl + D/code しちゃったもんだからSSH閉じてしまって、なんとUbuntuにログインできなくなってしまった。/p pUbuntuは coderoot/code というアカウントがなくてなんでも codesudo/code するか、 codesudo su/code で無理矢理rootになるしかないので、rootでログインしてchshしてやるという救済手段がとれず、にっちもさっちもいかなくなってUbuntuを再インストールした。/p pちょっと調べたら、こういうアクシデントを防ぐために、/etc/shells にzshを足さず、chshでデフォルトシェルにもしないという人もいるみたい。code.bashrc/code に次のように書くそうだ。/p div class=highlightprecode class=shspan class=kif/span span class=o[/span -f /bin/zsh span class=o]/span; span class=kthen/span span class=k /spanspan class=nbexec/span /bin/zsh span class=kfi/span /code/pre /div pこれだと何かのトラブルでzshが起動しないことがあってもbashでログインできるということらしい。zshがちゃんとしてるときはzshでログインするという理屈だ。/p pa href=http://labs.unoh.net/2010/05/zsh.htmlウノウラボ by Zynga Japan: zshはじめました。/a/p pしかしこれには結構重い副作用があるみたい。/p pa href=http://d.hatena.ne.jp/tyru/20100922/exec_bin_zsh_considered_harmful.bash_profileに「exec /bin/zsh」と書くのはやめたほうがいい - Humanity/a/p p一理ある。/p pというわけでUbuntuやrootでsshできない環境ででzshを使う場合は、何らかのトラブルでzshが起動しない、シェルにログインできなくなることを想定し、保険として普段はまったく使わない非常用のアカウントを作っておくと良いと思った。もちろんsudoersに指定しておかないと意味ないけどね。/p
p昨日と一昨日の二日間、TDD Boot Camp 福岡に参加した。/p h3 id=section参加しようと思ったわけ/h3 p勤めている会社にはテストがない。いや、テストはある。エクセルにテスト項目をたくさん書き出していって手動テストだ。テストコードがない。人力で三人くらいが夜なべしてテストする(だいたいスケジュールには遅延が発生する)。これはどうしたっておかしい。開発前に要件定義書、設計書を書いて開発して、開発が終わったらエクセルで長大なテストシートを作成し、手動テストを行う。そしてバグや思わぬ不具合が発見されるとプログラムに改修を加える。欠陥や不都合が発見される度に連動して設計書にも修正・変更が加えられ、Do Repeat Yourselfな感じになってる。毎日毎日ドキュメント作成などの開発以外のタスクに時間を割かれるので新しい技術に触れる機会がないし、遅くまで残って仕事してから帰宅するので趣味プログラミングで知見を広めることもできない(福岡に来てからのこのブログの更新状況を見ればおわかりいただけるかと)。この状況をなんとかしたいと思っていて、藁をもすがる思いでTDD Boot Campに参加した。/p h3 id=section-1感想/h3 p一日目は『プログラマが知るべき97のこと』の監修やTDDで有名な a href=http://twitter.com/t_wada@t_wada/a さんのレクチャーで、TDDとは何かが説明された。以下印象に残った点。/p ul li良いテスト ul li自動化されている/li li徹底している/li li何度でも実行可能/li li独立している/li liプロのコード ul liテストコードもプロダクトコードと同じ品質であることが求められる(リファクタリング、DRY原則の貫徹など)/li /ul /li /ul /li liTDD三原則 ul li単体テストコードを書く前に製品コードを書いてはいけない/li li適切に失敗する単体テストコードができるまで、次の単体テストコードを書いてはならない/li li単体テストコードに対応する以上に製品コードを書かない/li /ul /li liなぜTDDするのか ul li自分が完璧ではないことがわかっているから ul li最初から思い通りにコードを書けるほどに私たちは賢くない/li li最初から思い通りに動作するほど対象は単純ではない/li li素早く対象に近づき、フィードバックを得て方向修正をしながら開発を行う必要がある/li /ul /li /ul /li liテストの目的は健康 ul li変化に対応できるのは健康体のコードだけ/li li変化に対応できるのは健康体のチームだけ ul li毎日残業する、毎日レッドブル飲んだりしていてはダメ/li /ul /li /ul /li liTDDの導入効果 ul liMSやIBMでTDD導入後、欠陥の割合が4割から9割削減された。/li liコード実装時間は15%から35%増加した。 ul liしかし結果的にはバグが激減するので開発工数自体は減る。/li /ul /li /ul /li liTDDは才能ではなくスキル ul li練習すれば習得可能/li li量は質に転化する/li li写経しましょう! ul liPCにGitをインストールし、ページをキープできるブックスタンドを買って、ケント・ベック本をひたすら写経。ビルドを実行する度にコミットする。/li /ul /li /ul /li /ul pテストのみならず、自動化やバージョンコントロールの重要性が説かれた。/p p二日目には a href=http://twitter.com/bleis@bleis/a さんによるGitの効果的な利用方法やJenkinsを利用した継続的インテグレーションの実践例、 a href=http://twitter.com/akineko@akineko/a さんによるOMakeを利用した自動ビルド、自動テスト、自動コミットの話など。/p h3 id=section-2ペアプログラミングを体験した/h3 pペアプログラミングを生まれて体験した。 a href=http://twitter.com/mallowlabs@mallowlabs/a さんとRubyでペアプログラミングをさせてもらった。講師陣が出題する課題を解いていくというもの。当然テスト駆動。テスティングフレームワークにはRSpecを利用した。/p pWEB + DB PressなどのRSpec特集を写経したことはあったけど、時間制限がある中で、他の人とペアを組んでプログラムを書いていく作業はかなりエキサイティングだった。/p pただ自分のRubyスキルおよびVimのスキルが著しく劣っていたため、@mallowlabs さんの足を引っ張っていた感は否めない。正直申し訳なかったです。/p p全般的に、自分の知識のなさ、スキルのなさが実感できた/p p以下、初日に行ったFizzBuzz問題と主に二日目に取り組んだTwitterのタイムラインをカテゴリ分けするという課題の成果物。/p pa href=https://gist.github.com/879647TDD Boot Camp 福岡 — Gist/a a href=https://gist.github.com/878159TDDBC でペアプロした結果です — Gist/a/p h3 id=tddTDDをいかにして根付かせるか/h3 p勉強会に参加していきなりコードが書けるようになるわけでは当然ないので、継続的な勉強が必要だと感じた。いっぱい本を紹介してもらったので積ん読本を何冊か片付けたら『レガシー・コード改善ガイド』と『テスト駆動開発入門』を買おうと思った。/p
p昨日の続きのようなもの。LokkaをUbuntu上で動かそうといろいろやってます。passenger入れて、 codepassenger-install-nginx-module/code を実行しようとしたらエラーが出た。お前はrootじゃないからnginxインストールできひんわ、みたいなメッセージが出る。sudoったりrootになってインストールしようとすると今度はpassengerなんていうgemはないわ、って怒られる。sudoしたときには.rvm内のgemパッケージではなくシステムのgemパッケージを見ようとするっぽい。またrootになるとRVMではなくシステムのRubyが実行されるので同じくpassengerなんてgemないわ、って怒られる。システムのRubyは1.8.7だし、なるべくなら使いたくない。RVMのRubyを使ってpassenger + nginxな環境作れないのかよ、とググってたら以下のような記事を発見した。/p pa href=http://www.blog.bridgeutopiaweb.com/post/install-rvm-passenger-nginx-and-rails-3-on-ubuntu-lucid-lynx/Install RVM, Passenger, Nginx and Rails 3 on Ubuntu Lucid Lynx/a/p pなんと、RVMには codervmsudo/code というコマンドがあるらしい! 試しに/p div class=highlightprecode class=consolespan class=gp$/span rvmsudo passenger-install-nginx-module /code/pre /div pを実行してみたところ、お前はroot権限がないんじゃ〜とエラーが出ていたところも無事通過してnginxをインストールできてしまった。以前、sudoで無理矢理nginxをインストールしたときは、 codenginx.conf/code 内で、/p div class=highlightprecode class=nginx span class=kpassenger_root/span span class=s/home/morygonzalez/.rvm/gems/ruby-1.9.2-p136/gems/passenger-3.0.2/spanspan class=p;/span span class=kpassenger_ruby/span span class=s/usr/bin/ruby1.8/spanspan class=p;/span /code/pre /div pとなっていて大変気持ち悪かったし、Passengerも「PassengerとRubyの本体でバージョンの不整合があるだろヴォケ」みたいな警告出してた。それが codervmsudo/code のおかげで codenginx.conf/code に書き込まれる値も以下の通りとなるので、とりあえずPassenger(RubyGems)とRubyのバージョンが異なるというような問題は回避できる。/p div class=highlightprecode class=nginx span class=kpassenger_root/span span class=s/home/morygonzalez/.rvm/gems/ruby-1.9.2-p136/gems/passenger-3.0.2/spanspan class=p;/span span class=kpassenger_ruby/span span class=s/home/morygonzalez/.rvm/wrappers/ruby-1.9.2-p136/ruby/spanspan class=p;/span /code/pre /div pただ、なんでか分からないのだけどnginxがうまく動いてくれなくて、無事Webサーバーを起動できてない感じです。/p pそれにしてもRVMは、本当にきもいと思う。a href=http://d.hatena.ne.jp/rochefort/20100907/p1 title=rvmのirbで日本語入力できない - うんたらかんたら日記readlineとかまで.rvm内にインストールできる/aできるし、いったい何考えてるんでしょうかね。きもすぎて便利です。/p
pRVMを使ってます。RVMで入れたRubyがshebangに code#!/usr/bin/env ruby/code と書いたときに呼び出されて欲しいと思ってます。シェルから/p div class=highlightprecode class=rubyspan class=c1#!/usr/bin/env ruby/span span class=nbputs/span span class=noRUBY_DESCRIPTION/span /code/pre /div pなファイル(hoge.rb)があったとします。これを/p div class=highlightprecode class=consolespan class=gp$/span ruby hoge.rb /code/pre /div pとシェルから呼び出したときにはちゃんと/p div class=highlightprecode class=consolespan class=gp$/span ruby 1.9.2p136 span class=o(/span2010-12-25 revision 30365span class=o)/span span class=o[/spanx86_64-darwin10.6.0span class=o]/span /code/pre /div pと表示されます。しかしTextMateでRunしたときや、Apacheから同じshebangで呼び出したときには、systemのRubyが呼ばれます。/p pこれ、もう半年くらい解決方法探してる気がする。/p pTextMateでRunしたときにsystemのRubyが呼ばれるのはともかくとして(テストするときはシェルから呼び出すのでRVMのRubyで実行できる)、Apacheで新しめのRubyを使いたいときはどうすればよいのでしょう。まさかshebangに code~/.rvm/bin/ruby-1.9.2-p136/code とか書くんじゃろか。/p pcxxさんに質問したら a href=http://rvm.beginrescueend.com/deployment/system-wide/RVM: Ruby Version Manager - Installing RVM System Wide/a というURLを教えてもらった。今日は眠いのでまた今度試す。/p
pあけましておめでとうございます。なんか2010年後半は転職とか引っ越しとかあってあまりここに記事を書けなかったのが残念です。Rubyとか全然さわってねーし、JavaScriptも忘却曲線の彼方。というわけで2011年一発目はJavaScriptについて。/p pAutoPagerize対応なページで、読み込まれた2ページ目以降でもJavaScriptを動かす方法について調べてみた。oAutoPagerizeのos0xさんのページでまとめられてる。/p pa href=http://d.hatena.ne.jp/os0x/20090829/1251556449AutoPagerizeで継ぎ足された部分に自分のスクリプトを適用する方法あれこれ - 0xFF/a/p pいちばん手っ取り早そうだったので、以下のような書き方をした。/p div class=highlightprecode class=javascriptspan class=kif/span span class=p(/spanspan class=nbwindow/spanspan class=p./spanspan class=nxAutoPagerize/spanspan class=p)/span span class=p{/span span class=nbwindow/spanspan class=p./spanspan class=nxAutoPagerize/spanspan class=p./spanspan class=nxaddFilter/spanspan class=p(/spanspan class=nxfucintion/spanspan class=p(){/span span class=c1// 実行したい処理/span span class=p});/span span class=p}/span /code/pre /div pただ無名関数は呼び出せないので、二回書かなければならなくなる。これはアホっぽい。関数リテラルにして呼び出し用に codefunction init()/code みたいのを書き、その中から呼び出せばよい。そしてその codeinit()/code を上記 code// 実行したい処理/code 内にも書いてあげればオッケーだ(もちろん codewindow.onload/code で呼び出す必要もある)。/p pjQueryについては codelive()/code というメソッドがある。これは動的に生成された要素にも処理を適用してくれる非常にありがたいメソッドだ。しかし個人的な事情で、 codelive()/code というメソッドと一緒に、処理を一度しか実行しないというメソッド codeone()/code も適用している要素があり、これを二つ両立するのがjQuery的に無理っぽい。単純に処理実行のフラグを作って処理を分ければいいんだけど、これにもjQuery的なかっこいい書き方があることを知った。ネタもとはこちら。/p pa href=http://stackoverflow.com/questions/3796207/using-one-with-live-jqueryUsing .one() with .live() jQuery - Stack Overflow/a/p div class=highlightprecode class=javascriptspan class=nx$/spanspan class=p(/spanspan class=s1#39;処理を適用したい要素#39;/spanspan class=p)./spanspan class=nxlive/spanspan class=p(/spanspan class=s1#39;click#39;/spanspan class=p,/span span class=kdfunction/spanspan class=p(/spanspan class=nxe/spanspan class=p)/span span class=p{/span span class=kif/spanspan class=p(/spanspan class=nx$/spanspan class=p(/spanspan class=nxe/spanspan class=p./spanspan class=nxtarget/spanspan class=p)./spanspan class=nxdata/spanspan class=p(/spanspan class=s1#39;oneclicked#39;/spanspan class=p)/spanspan class=o!=/spanspan class=s1#39;yes#39;/spanspan class=p)/span span class=p{/span span class=c1//Your code/span span class=p}/span span class=nx$/spanspan class=p(/spanspan class=nxe/spanspan class=p./spanspan class=nxtarget/spanspan class=p)./spanspan class=nxdata/spanspan class=p(/spanspan class=s1#39;oneclicked#39;/spanspan class=p,/spanspan class=s1#39;yes#39;/spanspan class=p);/span span class=p});/span /code/pre /div pcodejQuery().data()/code 、なかなか便利そうだ。/p
p福岡工業大学で行われた、オープンソースカンファレンス福岡2010に行った。/p pa href=http://www.usp-lab.com/ title=Universal Shell Programing Laboratoryusp lab/aのシェルスクリプトで業務用基幹システムを開発する話が面白かった。一般的なプログラミング言語は使わずに、シェルで生のLinuxを使って作業を行わせる。DBは使わずデータはTextで持つ。HTTP関連のあれこれもシェルスクリプトで行う。このためセキュリティのことは考えないといけないらしいんだけど(フロントエンドとバックエンドがシェルスクリプトでつながってるため)、大手のシステム会社が100人月とかみたいな見積を出す案件を10人月程度でやったそう。具体的には無印良品のシステムとか。遅めに会場に入ったので資料は売り切れで貰えず、細かい数字は自信がないんだけど、無印のやつは一年間に10億円かかってたシステム関連の費用が2億円程度に抑えられるようになったそう。mknodとかsedコマンドを駆使した並列処理のデモは本当に面白かった。へー、シェルスクリプトだけでこんなにできるんだー、っていう感じ。1億行のテキストデータ処理を53秒で終わらせたりとか。「Linuxはなるべく生で使いましょう」という言葉がとても深く印象に残っている。Railsみたいな便利なフレームワークを使った開発とはまったく異なるけど、UNIXの「小さいものは美しい」という理念のもと、とんでもなく効率的に開発を行っている様がとてつもなくクールだった。/p
piTerm 2が素晴らしいということなのでiTermをぼちぼち使ってるんですけど、Vimを起動したときに矢印キーで移動できないことが分かった。「Vimで矢印キーでカーソル移動とか小学生かよ」みたいなご意見もあるでしょうけど、入力モードのときに移動したくなったら codej, k, h, l/code じゃ移動できないでしょ? そこで矢印キーですよ。/p piTermでVimを使っているときも矢印キーでカーソル移動できないものかと、軽くググってみたところ次のような記事に遭遇した。/p pa href=http://d.hatena.ne.jp/takimo/20080308/1205047505 title=MacBookのiTermでVimを使う時矢印キーで移動が出来ないときの解決方法 - Nobody is perfect.MacBookのiTermでVimを使う時矢印キーで移動が出来ないときの解決方法 - Nobody is perfect./a/p pこれを参考にとりあえず以下のように code.zshrc/code に書いた。/p div class=highlightprecode class=bashspan class=kcase/span span class=s2quot;${TERM_PROGRAM}quot;/span in iTerm*span class=o)/span span class=nbexport /spanspan class=nvTERM/spanspan class=o=/spandtterm span class=kesac/span /code/pre /div pしかし、これはちょっと自分的にはいただけなかった。/p div class=highlightprecode class=bashspan class=nbexport /spanspan class=nvTERM/spanspan class=o=/spandtterm /code/pre /div pってやると、termcap的な何かの作用で、Vimを閉じたときにコンソールを復元できなくなる(参照: a href=http://tech.portalshit.net/2010/07/07/finish-editing-then-restore-console/ title=Vimで編集を終了した後、元のコンソールの状態を復元したい \| tech.portalshit.net - CakePHP, Rails, JavaScriptVimで編集を終了した後、元のコンソールの状態を復元したい/a)。僕はVimを閉じた後はコンソールを復元したい派なので、このやり方は受け入れられなかった。/p pcode.termcap/code に何か書くことも考えたけど、 code.termcap/code で条件分岐する書き方が分からなかったのでさらにググってみた。すると外人が「iTermの設定で何とかできる」みたいなことを書いてるのを発見した。/p pa href=http://www.help2go.com/Tutorials/Mac_OS/Using_Arrow_Keys_in_iTerm_with_vi.html title=Help2Go - free computer help and advice - Using Arrow Keys in iTerm with viHelp2Go - free computer help and advice - Using Arrow Keys in iTerm with vi/a/p pなるほど、 code.vimrc/code とか code.zshrc/code とか側で回避する方法ばかり考えていたけどiTermで回避する方法を考えればよいわけか。/p pで、iTermを開いてみたところ、iTerm 1の頃から引き継いでいるBookmarkのDefaultの設定がよくなかったみたい。具体的には矢印キーそれぞれに code^[[A/code とか code^[[B/code みたいなキーが割り振られていて、このせいで矢印キーが使えなくなっていたわけだ。/p pLoad Presetから “Use xterm Defaults” を選んでみたところ、無事矢印キーでカーソル移動できるようになった。めでたしめでたし。/p
pRuby 1.9、Rails 3、RSpec 2で開発してる。いままでRubyとRailsになれるのに一杯一杯でテスト駆動開発できてなかったので、きちんとテストファーストでやることにした。/p pそんで環境を整えてたんだけど、RSpecはRails 3に合わせてVersion 2が出てるみたい。しかも結構変わってる。/p div class=highlightprecode class=consolespan class=gp$/span spec -c spec/* /code/pre /div pとかやってもエラーが出る。 codewhich spec/code すると code/usr/bin/spec/code と出ちゃう。どうやら codespec/code で発動されるのはRSpec 1.3のものみたい。/p pRSpec 2からはコマンド名が変更されており、テストコードを実行したいときは以下のように書くみたい。/p div class=highlightprecode class=consolespan class=gp$/span rspec -c spec/* /code/pre /div pこれできちんとテストコードが実行された。かと思いきやFailureが。/p pRuby 1.9で動かしてるから、コードの中に日本語を書くときは一行目に/p div class=highlightprecode class=rubyspan class=c1# -*- coding: utf-8 -*-/span /code/pre /div pと書いてテキストエンコーディングを明示してあげないといけない。/p
p動かしてるサイトのCakePHPのバージョンを最新版の1.3.4に上げようと思って、Media PluginもCakePHP 1.3対応バージョンの1.3alphaにアップデートしようとした。/p pとりあえず本体を codegit clone http://github.com/cakephp/cakephp.git/code し、Media Pluginを codegit clone http://github.com/davidpersson/media.git/code してみた。/p pMedia Plugin 1.3での設定方法とか調べてみようと思って、GitHub上のWikiのページを探すんだけど見つからない。なんと、作者サマはVer 1.3からWikiを消しちゃったみたい! そんまま動かしてみたところではMedia Plugin動いてないみたい。Mediumヘルパーがないというエラーが出る。プロジェクトの中の codedocs/code ディレクトリにドキュメントが格納されていたのを発見したので(a href=http://github.com/davidpersson/media/tree/1.3/docs/ title=docs at 1.3 from davidpersson's media - GitHubdocs at 1.3 from davidpersson’s media - GitHub/a)そこを参考にしながらMedia Plugin 0.6から1.3へのMigration作業をやったんだけど、とうとうできなかった。/p pまず第一に、クラス名が変わってる。codeMedia.Medium/code だったのが codeMedia.Media/code になってる。Viewファイル内での変数も code$medium/code ではなく、 code$media/code になってる。そしてメソッドとかもHTML5対応とかで結構変わってるみたい。/p pさらに、media processing 関連のクラスが分割されて別のライブラリとしてMedia Pluginの中に含まれてる(a href=http://github.com/davidpersson/mm title=davidpersson's mm at master - GitHubdavidpersson’s mm at master - GitHub/a)。これが結構わかりにくい。なんかImagick必要ぽくて、本番環境じゃインストール権限ないので使えないし、結局ここで諦めてしまった。/p pMedia PluginはVer 0.6のWikiがあった頃もなんかドキュメンが見づらかったし、1.3になってドキュメントはただのテキストファイルになり、しかもメソッドについての解説がないので結局本体のコードを読むしかない。/p pRubyのライブラリはたいていRdocとかついててドキュメントが充実してるので、あれに慣れるとドキュメントがわかりにくいライブラリやプラグインは億劫に感じてしまう。/p
pいやまぁテキストエディターにはいろいろあるわけでして、皆さんEmacsとかVimで日夜しこしこコードを書いておられると思うんですけど、僕はGUIしか使えない情報弱者なので主にTextMateを使ってます。/p pTextMateで便利なのが “Run” っていう機能です。Rubyのコードを書いていて、kbd⌘/kbd + kbdR/kbd でさくっと実行結果を確認できます。いちいちTerminal開いて/p div class=highlightprecode class=consolespan class=gp$/span ruby hogehoge.rb /code/pre /div pとか面倒くさいことをやらずにすみます。/p pで、これからが本題なんですけど、先月Ruby 1.9.2がリリースされて、さらに codegem update/code でRails 3が入るようになってしまったので、お試しでRuby 1.9.2とRails 3を使ってみることにしました。しかし1.8系を完全に捨てることは恐ろしいので、RVMを使って複数のバージョンのRubyを切り替えながらしばらく過ごしてみることにしたわけです。/p p上に書いたとおり僕ちゃんは情報弱者なのでTextMateに依存したコーディングライフを送っており、kbd⌘/kbd + kbdR/kbd で動くRubyもRVMのRubyにしたいと思ったのですが、これが分からなかった。RVMのサイトを見たらいろいろごちゃごちゃやり方が書いてあるんだけど(a href=http://rvm.beginrescueend.com/integration/textmate/ title=RVM: Ruby Version Manager - Textmate Integration with RVMRVM: Ruby Version Manager - Textmate Integration with RVM/a)、結局この通りにやってもうまくいかず。/p pしかし先ほどなにげなく/p div class=highlightprecode class=consolespan class=gp$/span rvm 1.9.2 --default /code/pre /div pとしてあげたところ、TextMateでもRVMのRubyが走るようになりました。/p
pみなさん、クリッカブルマップしてますか? あんなくそみたいなもの使って地図をつくるなんて発狂しそうなこと、ここを読みそうな人はやってないと思いますが、僕の職場のお客さんとか上司は「Google Mapsには心がこもってない」とか言うので、クソみたいイラストをクリッカブルマップにして地図を作ってるんですよ。まじでかわいそうな僕ちゃん。/p pご存じない方のためにクリッカブルマップの作り方を説明しておくと、まず画像を作り、それをHTMLに貼り付け、HTMLオーサリングツール(うちの職場ではDreamWeaver)のGUIエディタでちまちま画像上のクリッカブルにしたい位置を選択するという、血尿が出そうなくらい面倒くさい作業を強いられます。/p p最悪なことにこのクリッカブルマップのあるページ、頻繁に更新依頼が来るのですよね。依頼が来る度に就業時間中の快適なネットサーフィンが妨げられるので、一発JavaScriptを書いて画像上の座標を取得することにしました。いちいちクソみたいに重いAdobe DreamWeaverとか立ち上げてられるか。/p pコードはこんな感じ。/p div class=highlightprecode class=htmlspan class=ntlt;htmlgt;/span span class=ntlt;headgt;/span span class=ntlt;scriptgt;/span span class=kdfunction/span span class=nxgetPosition/spanspan class=p(){/span span class=kdvar/span span class=nxx/spanspan class=p,/span span class=nxy/spanspan class=p;/span span class=kdvar/span span class=nximage/span span class=o=/span span class=nbdocument/spanspan class=p./spanspan class=nxgetElementById/spanspan class=p(/spanspan class=s1#39;image#39;/spanspan class=p);/span span class=nximage/spanspan class=p./spanspan class=nxonclick/span span class=o=/span span class=kdfunction/spanspan class=p(/spanspan class=nxe/spanspan class=p)/span span class=p{/span span class=nxx/span span class=o=/span span class=nxe/spanspan class=p./spanspan class=nxlayerX/spanspan class=p;/span span class=nxy/span span class=o=/span span class=nxe/spanspan class=p./spanspan class=nxlayerY/spanspan class=p;/span span class=nbdocument/spanspan class=p./spanspan class=nxgetElementById/spanspan class=p(/spanspan class=s2quot;pointXquot;/spanspan class=p)./spanspan class=nxvalue/span span class=o=/span span class=nxx/spanspan class=p;/span span class=nbdocument/spanspan class=p./spanspan class=nxgetElementById/spanspan class=p(/spanspan class=s2quot;pointYquot;/spanspan class=p)./spanspan class=nxvalue/span span class=o=/span span class=nxy/spanspan class=p;/span span class=p}/span span class=p}/span span class=nbwindow/spanspan class=p./spanspan class=nxonload/span span class=o=/span span class=nxgetPosition/spanspan class=p;/span span class=ntlt;/scriptgt;/span span class=ntlt;/headgt;/span span class=ntlt;bodygt;/span span class=ntlt;divgt;/span span class=ntlt;img/span span class=nasrc=/spanspan class=squot;path/to/imagequot;/span span class=naid=/spanspan class=squot;imagequot;/span span class=nastyle=/spanspan class=squot;position: absolute; top: auto; left: auto; width: 500px; height: 332pxquot;/span span class=nt/gt;/span span class=ntlt;/divgt;/span span class=ntlt;form/span span class=naaction=/spanspan class=squot;/quot;/span span class=namethod=/spanspan class=squot;postquot;/spanspan class=ntgt;/span span class=ntlt;input/span span class=natype=/spanspan class=squot;textquot;/span span class=naid=/spanspan class=squot;pointXquot;/span span class=naname=/spanspan class=squot;pointXquot;/span span class=navalue=/spanspan class=squot;quot;/span span class=nt/gt;/span span class=ntlt;input/span span class=natype=/spanspan class=squot;textquot;/span span class=naid=/spanspan class=squot;pointYquot;/span span class=naname=/spanspan class=squot;pointYquot;/span span class=navalue=/spanspan class=squot;quot;/span span class=nt/gt;/span span class=ntlt;input/span span class=natype=/spanspan class=squot;submitquot;/span span class=navalue=/spanspan class=squot;発射!quot;/span span class=ntgt;/span span class=ntlt;/formgt;/span span class=ntlt;/bodygt;/span span class=ntlt;/htmlgt;/span /code/pre /div pFirefoxでしか動作確認してないけど多分IEでは動かないと思います。ここのサイトを参考にさせてもらいました。/p pa href=http://d.hatena.ne.jp/sandai/20091105/p1 title=座標取得するプロパティのそれぞれの違い - 三等兵座標取得するプロパティのそれぞれの違い - 三等兵/a/p
pRubyKaigi 2010に行ったのでその感想を軽く。/p h4 id=section自分のスペック/h4 pRubyは使い始めて8ヶ月くらい。元々何もできなかったのでいまも初心者レベル。プレゼンテーション聞いてても分からないことが多かった。/p h4 id=section-1感想/h4 p永和システムマネジメントdel永和システム/delさんの「a href=http://rubykaigi.org/2010/ja/events/23 title=日本Ruby会議2010, 8月27日〜29日Head First ふつうのシステム開発/a」は面白かった。プログラミングのやり方を人から教わったことがないので、普通の会社はこうやって開発してるんだってのが分かった。テストの様子を見られて参考になった。あとVimがすごくカスタマイズしてあってすごかった。用事があって途中までしか見られなかったのが残念。/p pMongoDBについてのプログラム(a href=http://rubykaigi.org/2010/ja/events/73 title=Practical Ruby Projects with MongoDBPractical Ruby Projects with MongoDB/a)で、気にはなっていたけどよく分からなかったMongoDBのことがより一層気になった。情報の連結とかそういうコムズイことはSQLでやるんじゃなくてプログラム側でやるべき、ってことなのかな。/p pクックパッドのセッションも見学した。CTO氏が質疑応答で「専属デザイナーはいなくてデザインもできるプログラマーがデザインやってる」って言ってたのにびっくりした。大規模サービスをやってたら負荷分散のテクニックとか参考になったかもだけど、自分が作ってるサイトは多くても5000UU/日くらいなので「ふーん」という感じで聞いてた。/p p東京とつくばの移動に時間がかかったこと、他にも予定があったこと、帰りの飛行機の都合、などなどであまりゆっくり参加できなかったのが残念だったです。28日は用事があったので基調講演見られないから生Matzを拝むの諦めてたけど、Jeremy Kemperの基調講演がキャンセルになったかわりにトークセッションがあってて、そこにMatzも登場しててRubyの教祖を拝めたのでまぁ良かったと思います。あとジュンク堂RubyKaigi支店でで技術書買いすぎて散在した!/p h4 id=section-22010年9月26日修正/h4 pすみません、永和システムマネジメントさんのことを「永和システムさん」と書いてました。はてブのコメント欄で角谷さんに指摘されてた!/p
pa href=http://give-me-money.g.hatena.ne.jp/cxx/20100802/1280760811 title=MacPortsからHomebrewに移行した - cxxの日記 - give-me-moneyグループシャレオツプログラマーはみんなMacPortsからHomebrewに移行しつつあるっぽい/aので、真似してみることにした。/p h3 id=homebrewなんでHomebrew?/h3 pそもそもなんでみんな移行するのか? なんかMacPortsはバッドノウハウの塊らしい。/p pa href=http://twitter.com/hitode909/status/18526396749 title=Twitter / シャブ山シャブ彦: MacPortsはバッドノウハウの集合だったから,他 ...Twitter / シャブ山シャブ彦: MacPortsはバッドノウハウの集合だったから,他 …/a/p pMacPortsの何がバッドノウハウなのかちょっとよく分からなかったんだけど、でもよく考えてみたらMacPortsは code.bash_profile/code とか code.zshrc/code とかにへんてこりんなパスを埋め込まないといけないし、PerlとかRubyは一行目に/p div class=highlightprecode class=perlspan class=c1#!/usr/bin/perl/span /code/pre /div pとか /p div class=highlightprecode class=rubyspan class=c1#!/usr/bin/env ruby/span /code/pre /div pとか書くのに使ってるバイナリ本体は code/opt/local/bin//code にあるとかは気持ち悪いっちゃ気持ち悪い。/p pHomebrewはLinuxのパッケージ管理ソフトみたいに code/usr/local/bin//code とかに何でもインストールするので精神衛生上ベターだ。/p pHomebrewのインストール自体はとても簡単。パッケージ管理スクリプトをRubyで書くってのも、UNIXのことよく分かってない僕にはなかなかよいかもしれない。詳しいことは公式Wikiとかを見て下さい。/p pa href=http://mxcl.github.com/homebrew/ title=Homebrew — MacPorts driving you to drink? Try Homebrew!Homebrew — MacPorts driving you to drink? Try Homebrew!/a/p h3 id=vimVimのインストールではまった/h3 pHomebrew自体は簡単に入った。試しにVimをAppleがコンパイルしたVersion 7.2のものから新しめの7.3に上げて、ついでにRubyオプション入りでコンパイルしたかったので/p div class=highlightprecode class=consolespan class=gp$/span brew install vim /code/pre /div pしてみた。しかしながら/p div class=highlightprecode class=consolespan class=goError: No available formula for vim/span /code/pre /div pと出た。GUI版のMacVimはFormulaパッケージがあるらしいけど、フツーのVimはないらしい。「えー、自分でFormulaファイルを書かなきゃいけないの〜?」って感じだったんだけど、GitHubでテケトーに検索したらいろいろ出てきたので、 code/usr/local/Library/Formula//code に codevim.rb/code を作ってコピペした。/p pa href=http://github.com/adamv/homebrew/blob/duplicates/Library/Formula/vim.rb title=Library/Formula/vim.rb at duplicates from adamv's homebrew - GitHubLibrary/Formula/vim.rb at duplicates from adamv’s homebrew - GitHub/a/p pそんで今度は意気揚々と/p div class=highlightprecode class=consolespan class=gp$/span brew install vim /code/pre /div pしてみたんだけど、なんとmakeに失敗する。Python.frameworkを参照してるときにエラーが出てるっぽい。/p div class=highlightprecode class=consolespan class=gold: warning: in /Library/Frameworks//Python.framework/Python, missing required architecture x86\_64 in file/span /code/pre /div pAppleが配布したのではないPythonを使ってるとこういうエラーが出るとかなんとか外人が言ってる。/p pa href=http://vim.1045645.n5.nabble.com/Python-link-errors-td1214971.html title=Nabble - Vim - Mac - Python link errorsNabble - Vim - Mac - Python link errors/a/p p要するに64bit版のPython.frameworkを入れれば良さそうだった。何も考えずにHomebrewで codebrew install Python/code とかやって code/usr/local/bin/python/code に新しいPythonを入れてみたりしたんだけど、これは意味なかったっぽい。大人しくPython公式サイトからPython 2.7のインストーラーパッケージをダウンロードしてきてGUIでインストールした。/p pa href=http://www.python.org/download/releases/ title=ReleasesReleases/a/p pその後、もう一度 codebrew install vim/code をしてみたところ、無事make完了。codevim --version |grep ruby/code で/p div class=highlightprecode class=consolespan class=go+ruby/span /code/pre /div pとなった。/p pまだApacheとかRubyGemsとかはMacPorts版を使っているけど、割と早い段階でHomebrewに移行して、シャレオツプログラマーの仲間入りをしようと思います。/p
p80個近くある静的HTMLファイルをシステム化する必要が生じたので、HTMLをHpricotでスクレイピングしたあと、抽出したデータをSQLiteにぶっ込んだ。しかしSQLiteにぶっ込んだあとでデータの一部をいじりたくなった。そこでRailsのActiveRecordを単体で使ってみた。/p h3 id=activerecordなんでわざわざActiveRecordを使うのか/h3 pいやそりゃもちろんSQL書くのが怖いからですよ。というのは半分冗談なんですけど、CakePHPはSQLite 2にしか対応しておらず、SQLite 2は何かと制限が多い。replace関数が使えんとか。temp tableとか作るのかったるいし、フレームワークばっかり使っててSQLはあんまりよく分からないのでActiveRecordを使った次第です。/p h3 id=section作業詳細/h3 pこのシステム化するプロジェクト自体はCakePHPで動いており、DBはSQLite2。デフォの状態だとRailsは codesqlite3-ruby/code しかインストールしないので、ActiveRecordからSQLite2なDBを操作することができず若干まいっちんぐだったんだけどなんとかでけた。ちなみにやったのはCRUDのReadとUpdateね。/p h4 id=section-1やったこと/h4 pとりあえず以下のようなファイルを用意。各レコードの codename/code フィールドの “hogehoge” という部分なのが邪魔なので削りたかった。/p div class=highlightprecode class=rubyspan class=c1#!/usr/bin/env ruby/span span class=nbrequire/span span class=s2quot;rubygemsquot;/span span class=nbrequire/span span class=s2quot;sqlitequot;/span span class=nbrequire/span span class=s2quot;active_recordquot;/span span class=noActiveRecord/spanspan class=o::/spanspan class=noBase/spanspan class=o./spanspan class=nestablish_connection/spanspan class=p(/span span class=ss:adapter/span span class=o=gt;/span span class=s2quot;sqlitequot;/spanspan class=p,/span span class=ss:database/span span class=o=gt;/span span class=s2quot;path/to/dbquot;/span span class=p)/span span class=kclass/span span class=ncHoge/span span class=olt;/span span class=noActiveRecord/spanspan class=o::/spanspan class=noBase/span span class=kend/span span class=nhoges/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nfind/spanspan class=p(/spanspan class=ss:all/spanspan class=p)/span span class=nhoges/spanspan class=o./spanspan class=neach/span span class=kdo/span span class=o|/spanspan class=nhog/spanspan class=o|/span span class=nhog/spanspan class=o./spanspan class=nname/spanspan class=o./spanspan class=ngsub!/spanspan class=p(/spanspan class=sr/hogehoge//spanspan class=p,/span span class=s2quot;quot;/spanspan class=p)/span span class=nhoge/spanspan class=o./spanspan class=nsave/span span class=kend/span /code/pre /div pまず最初に、 codeno such file to load -- sqlite/code みたいなエラーが出た。要するに「お前SQLite 2のアダプター入れてねえだろ」というエラー。とりあえず codesudo gem install sqlite-ruby/code したんだけど、それでも codeno such file to load — sqlite/code が出るのでMacを再起動したら「Rails 3ではSQLite 2はdeprecatedだからさっさとSQLite 3に移行しろや」みたいなメッセージは出るもののちゃんとDBの内容を読み込めた。CRUDのReadはでけた。/p pしかしUpdateの部分で失敗。Railsの感覚で codehoge.save/code とかやったんだけどこれは意図したとおりに機能しなかった。しょうがないのでRailsのAPIリファレンスを見ながら、 codeupdate_attribute()/code というメソッドをぶちかましてやった。こんな感じ。/p div class=highlightprecode class=rubyspan class=nhoges/spanspan class=o./spanspan class=neach/span span class=kdo/span span class=o|/spanspan class=nhog/spanspan class=o|/span span class=kif/span span class=nhog/spanspan class=o./spanspan class=nname/span span class=o=~/span span class=sr/hogehoge(.*)//span span class=nhog/spanspan class=o./spanspan class=nupdate_attribute/spanspan class=p(/spanspan class=s2quot;namequot;/spanspan class=p,/span span class=vg$1/spanspan class=p)/span span class=kend/span span class=kend/span /code/pre /div pこれで狙ったことができました。/p pRubyいいわー。ほんといいわー。/p
p外タレのJekyllブログを見てると、シャレオツな感じでコードがシンタックスハイライトされてる。どうもPygmentsというやつを使うらしい。公式Wikiでも触れられていて、コードをハイライトさせたいときは codejekyll --pygments/code しろや、みたいなことが書いてあるんだけど(a href=http://wiki.github.com/mojombo/jekyll/liquid-extensions title=Liquid Extensions - jekyll - GitHubLiquid Extensions - jekyll - GitHub/a)、そういうオプションつけてもコードは全然色つきにならず、「サギやんけ」とか思ってた。/p pしかしマニュアルをよく読むと、PygmentsってのはPython製のソフトで、こいつを別途インストールする必要があるらしい。なるほどそういうことだったのか。そういうわけで/p div class=highlightprecode class=consolespan class=go $ port search pygments/span /code/pre /div pしてみたところ、MacPortsでは三つヒットした。/p div class=highlightprecode class=consolespan class=go py-pygments @1.0 (python, devel)/span span class=go Python syntax highlighter/span span class=go /span span class=go py25-pygments @1.0 (python, devel)/span span class=go Python syntax highlighter/span span class=go /span span class=go py26-pygments @1.3.1 (python, devel)/span span class=go Python syntax highlighter/span span class=go /span span class=go Found 3 ports./span /code/pre /div pしかしSnow LeopardにはPython 2.6.1が入ってるので、/p div class=highlightprecode class=consolespan class=go $ easy_install Pygments/span /code/pre /div pでもオッケーかも知れない。僕は職場に持ち込んでMacBookにはMacPortsから codepy26-pygments/code を入れた。そしたらdependencyが発動してPythonとかXorg何とかというもののダウンロードも始まり、 code/opt/local/bin//code に codepython-2.6.5/code が入ったが、長々と時間がかかった。supa href=#footnote-34-1※1/a/sup/p pインストール完了後、これでシャレオツシンタックスハイライティングできるようになったと思い、意気揚々と/p div class=highlightprecode class=consolespan class=go $ jekyll --pygments/span /code/pre /div pしてみたのだが、一向にハイライトされない。なんか「pygmentizeとか見つからないし」みたいなエラーが出る。なんでじゃ〜とイライラしながら公式Wikiを読んでると、次のような記述があった。/p blockquote pthe pygmentize binary must be in your path/p /blockquote pそうなのよ。 codepygmentize-1.3.1/code っていうバイナリファイルはあってパスは通ってるんだけど、 codepygmentize/code そのものがないのよ。そういうわけで/p div class=highlightprecode class=consolespan class=go $ sudo ln -s /opt/local/bin/pygmentize-1.3.1 /opt/local/bin/pygmentize/span /code/pre /div pしてやった。すると codepygmentize/code というバイナリファイルにパスが通るので、めでたくシャレオツシンッタクスハイライティング環境が手に入った。ちなみにCSSはa href=http://github.com/mojombo/tpw/tree/master/css/syntax.css title=syntax.cssGithub互換のもの/aを拾ってきて入れといた。/p hr / p id=footnote-34-1※1 この記事を書いている自宅のMacBook Proには `sudo easy_install Pygments` で入れてみたが、一瞬でインストール完了した。またシンボリックリンクを貼る手間とか必要なく、インストールしただけでパスも通ってた。そういうわけなのでMacPorts経由のインストールはオヌヌメしませんです。よい子のみなさんは `easy_install` しちゃいましょう。/p
pAuthlogicとAuthlogic-OAuthでキメてやろうと思ってたのに全然うまくいかないし。Authlogic-OAuth、去年から全然更新されてないじゃん。Railsは便利なプラグインいっぱいあるけど、メンテが止まってることも多い。プラグインに頼りまくってサイト作ってると死ぬこともあるなーと思った。やりたいことは自分でもやれるようにしとく必要あるし、自分の手に余ることはやろうとしない方がいいと思った。できるところからコツコツと、と37シグナルズの本にも書いてあるし。/p
pNECの安サーバーを買ってサーバーを作ってるんですけど、SSHでエラーが出て困ってます。OSはUbuntu Server 10.04.1 LTS。/p pまずSSHのおさらいを。クライアント側で/p div class=highlightprecode class=consolespan class=gp$/span mkdir -p .ssh span class=gp$/span ssh-keygen -t rsa (以下略) /code/pre /div pしたのち、サーバー側の code/etc/ssh/sshd_config/code の codePasswordAuthentication/code を codeon/code にし、パスワードでSSH接続できるようにして/p div class=highlightprecode class=consolespan class=gp$/span scp id_rsa.pub username@hoge.com:.ssh/authorized_keys /code/pre /div pするか、あるいはUSBフラッシュメモリで鍵をサーバーに移す。その後サーバー側で code.ssh//code と code.ssh/authorized_keys/code のパーミッションをそれぞれ700と600に変えてあげるわけですよね。/p pいっぺんクライアント側で codeid_rsa.pub/code を作ってたらそれ以降は単純にこれを接続先のサーバーにコピーしてあげればおk。ここまで合ってますかね?/p p前から使ってる職場内だけで使うサーバーにも同じUbuntu Serverを入れてるんですけど、こっちでは全くトラブルがない。それなのに新しいサーバーでは/p div class=highlightprecode class=consolespan class=goPermission denied (publickey)./span /code/pre /div pというエラーが頻繁にお出になるのですよ。/p pしかしこのエラー、常に出る訳じゃないんですね。サーバーを直接操作して/p div class=highlightprecode class=consolespan class=gp$/span sudo /etc/init.d/ssh restart /code/pre /div pしてあげると消える訳ですね。そんでしばらくクライアントからSSHで接続したり切断したりを繰り返していると、あるとき突然、/p div class=highlightprecode class=consolespan class=goPermission denied (publickey)./span /code/pre /div pとなるわけです。まじでストレスフル。つか、このサーバーは公開用に使うものなので、こんな感じでSSHが不安定だとかまじで困るんですけど。/p p前述の codePasswordAuthentication/code を codeon/code にしとけば、公開鍵認証に失敗した後もパスワードで認証することができるんですが、パスワード認証はなんだか怖いので使いたくないのですよね。どいうしたものか。/p pググったらSSHのプロトコルを1と2併用にしたら解決するという情報が出てきたのですけど、これやったら “Disabling protocol version 1. Could not load host key” というエラー?が出てしまったので多分僕の環境では意味なし。「RSAキーやめてDSAにしたらエラーでなくなった」(a href=http://miyazaki.ddo.jp/mt3/blog/zaurus/20060405-2343.html title=ぷらぷらブログ \| OpenSSH を導入。接続に四苦八苦!ぷらぷらブログ | OpenSSH を導入。接続に四苦八苦!/a)という情報もあるけど面倒くさいのでまだ試していません。/p
pa href=http://twitter.com/ningengasinu@ningengasinu/a 様みたいに、自分で作ったボットに「日記書いた」ってしゃべらせようと思って、増田のRSSを使わせてもらおうと思ったんだけど、Rubyの codeRSS::Parser/code で読み込もうとすると code500 Internal Server Error/code が返ってきてしまう。ブラウザから読み込むときはエラーとか出ないんだけど。/p pしょうがないので codeopen-uri/code を使って codeUser-Agent/code を偽装してRSSを読みに行ったところ、正しくレスポンスが返された。しょうがないので codeRSS::Parser/code は使わず、 codeHpricot/code を使った。/p p増田ってbotのアクセス弾いてるわけですね。これがネットの闇ですか……/p
ptilyさんのgista href=http://gist.github.com/427398 title=gist: 427398gist: 427398/aを使わせてもらってTwitterのボットを何個か作ってみた。結構楽しいですね。/p pしかしボットが短時間に何度も同じ発言を繰り返してフバいので、日付が変わるまでは重複発言をしないようにしてみようと思った。Rubyは 配列 - 配列 みたいなエロいことができるみたいなので、/p div class=highlightprecode class=rubyspan class=nnew_tweets/span span class=o=/span span class=nneta_tweets/span span class=o-/span span class=nused_tweets/span /code/pre /div pとかしてみようとした。/p pa href=http://gist.github.com/427398 title=gist: 427398gist: 427398/a自体がTokyo Tyrantを使っているので、これでなんとか出来ないかなと思った。しかし coderdb.put/code しようとすると、 codeArgumentError/code というのが発生してしまう。ひょっとしたらTokyo Tyrantって配列とかを保存するもんじゃないのかな。/p
pOAuthを導入しようとした。Twitterのだけなら何とか拾ってきたコードで動くとこまで持ってけてたけど、どうせやるならいろんなOAuth Providerに対応したい。oauth-pluginってgemを使えば簡単に沢山のOAuth Providerに対応できるみたいなので導入しようとしたけど、これがくせ者だった。/p pまずoauthとoauth-pluginをただ入れるだけじゃ動かない。 qacts_as_authenticated, restful_authentication or restful_openid_authentication/q というプラグインが入ってて、ユーザー認証をこれらのgemに任せてないとダメ。/p p作者がrestful_authenticationをすすめてたのでこれを導入した。(usersテーブルの構造自体が変わるので、ただ単にインストールするだけじゃなくて coderake db:drop/code して古い codedb/migrate/(日付)_create_users.rb/code を削除し、もう一回 coderake db:migrate/code しないといけない。さらにControllerとかViewとかもいじらなきゃいけないので地味に結構面倒くさい。/p pしかし何度やってもうまくいかない。「 codelogin_required/code みたいなメソッドねーし」とかエラーが出る。どうやら昔の restful_authentication にはそういうメソッドがあったらしんだけど、現在の restful_authentication からは削除されてるらしい。他にも codecurrent_user/code っていうのも未定義で、この辺のエラーのおかげで完全に萎えた。/p pそういうわけで一週間くらいOAuth対応に向けて頑張ってたけど諦めました。TwitterだけOAuth認証に挑戦してみる。とってきたOAuth Tokenの扱いとかに若干不安があるけどうまくいくかしら。/p
pやってみた。以下を参考にした。/p pa href=http://www.taknado.com/en/2009/03/26/deploying-a-jekyll-generated-site/Deploying a jekyll generated site/a/p pこれもうむかし.macとかについてたiBlogとかわらんわ。GUIのクライアントはないけど、VimとかCodaとか好きなエディタ(TextMateで日本語がネイティブに扱えたらなー)で記事書いて、gitで codegit push/code するだけ。/p pで、やり方なんですけどちょっとgitに慣れてない人には複雑かもしれない。三つgitのリポジトリを用意する必要がある。/p pまず記事を作成するパソコンでgitとjekyllのセットアップをしたあと、リポジトリを作る(リポジトリ1)。その後Dreamhostの公開ディレクトリでないところに空のリポジトリを作る( codegit --bare init/code )。ここでは codeblog.git/code という名前にしましょう(リポジトリ2)。そんでそこにリポジトリ1をpushする。その後リポジトリ2の code/blog.git/hooks//code に codepost-update/code というファイルを作り、以下のように書く。ファイルに実行可能なアクセス権を与えることを忘れずに。/p div class=highlightprecode class=bash span class=c#! /bin/sh/span span class=nbunset /spanGIT_DIR span class=oamp;amp;/span span class=nbcd/span span class=nv$HOME/span/tech.portalshit.net/ span class=oamp;amp;/span git pull /code/pre /div pそんでもって codegit clone blog.git lt;公開用のディレクトリ名gt;/code する(リポジトリ3)。リポジトリ1から公開用ディレクトリにリポジトリがコピーされるので、この中に含まれる code_site/code というディレクトリを panel.dreamhost.com で公開ディレクトリとして設定すると、codegit push/code する度にhookが発動されて、めでたく記事が公開されるという次第です。/p h3 id=sectionまとめ/h3 pまとめると、/p ol li記事を作成するローカルリポジトリ/li liローカルリポジトリをpushするリモートリポジトリ/li liリモートリポジトリをcloneする公開用リポジトリ/li /ol pの三つが必要なことを忘れないようにしてくだしあ。/p pこれであなたもハイド博士だ!/p
pRailsでOAuthを使ってTwitterとかで認証させたい。oauth-pluginを使おうとしてるけど全然うまくいかない。イメージとしてはこんな感じ。/p pimg src=http://tech.portalshit.net/images/27-oauth.png alt=OAuthの利用イメージ //p p疑問点がいくつかある。/p ul li pUserモデルで codevalidate_presence_of/code をパスワードフィールドにかけてるけど、OAuth経由でユーザーが追加されたときはどうすればいいんだろう。OAuth経由ではパスワードは預からないので、 codevalidate_presence_of/code でエラーが出るはず。/p /li li pUserモデルで codehas_many :oauth_tokens/code とかリレーションの設定をしてしまったとして、OAuth経由ではなく普通にサインアップしたユーザーの扱いはどうなるんだろう? 「 codeoauth_tokens/code にそんな codeuser_id/code の人いないし」みたいなエラーが出るような気がする。/p /li /ul p他にもいろいろ気になる点があったような気がするけど分からなくなってしまった。/p
pFreeBSDでVimを起動しファイルを編集したあと、 code:q/code でVimを終了させてるのに元のコンソールに戻らなくてなんか嫌だなーと思っていた。MacもUbuntuもDreamHostのDebianもVimを閉じると元に戻るのに、職場の本番環境のFreeBSDだけこれなの。ファイル編集前のコンソールの履歴とかを見たいこともあるので、Vimが終了したら元の画面に戻るようにしたいと随分長いこと思っていたんだけど、たったいまようやく出来たのでメモっときます。/p pちなみにVimには coderestorescreen/code とかいうオプションがあるらしく、必死で.vimrcにこの設定を書いてたけど、これはなんかWindowsのVim専用のオプションらしいのでマカーやUNIXユーザーの方はこれを設定しても無駄です。/p p情報元は a href=http://d.hatena.ne.jp/lurker/20061118/1163810847 title=フルスクリーンアプリを終了したときに元のコンソールの状態に復元する - 技術メモ帳フルスクリーンアプリを終了したときに元のコンソールの状態に復元する - 技術メモ帳/a というページ。/p pFreeBSDの場合、 code/etc/termcap/code ってのの中にフルスクリーンアプリを終了したときにコンソールに戻るかどうかを設定する場所があって、こいつを変更すればよいらしい。/p pしかし自分はこのサーバーでroot権限を持ってない。なので codecp /etc/termcap ~/.termcap/code したあと codechmod 644 ~/.termcap/code して codevim ~/.termcap/code し、自分の使ってるターミナルの環境に合わせて設定を変更してやるとOK。/p p僕の場合はMacの純正ターミナルを、シェルはzshで使っている。 codeecho $TERM/code してみると codexterm-color/code と表示されるのでxterm-colorの設定が書いてあるところをいじった。/p pくわしくは上のリンク先を見てもらうといいんだけど、とにかく codete/code ってのと codeti/code ってのがあって、これをMacの場合は codete=\E7\E[?47h/code 、 codeti=\E[2J\E[?47l\E/code としてあげればいい。そんでシェルの設定ファイルに codeexport $TERMPATH=$HOME/.termcap/code と書いてやり、一端ログアウトして再ログインするとめでたくVimを終了したときにコンソールが復元されるようになります。/p
pCakePHPで動かしているサイトをCakePHP 1.2ベースからCakePHP 1.3ベースに変更作業中。その課程で気がついたことをメモしておきます。/p ol licode$html-gt;link()/code などHTMLヘルパーでエスケープを codefalse/code にしたいときは code$options['escape']/code を使う。/li licode$cakeDebug/code は廃止されたのでエラーが出る。/li licode$sessions-gt;flash()/code は codeecho $sessions-gt;flash()/code とする必要がある。また AppController でヘルパーとして呼び出さなければならない。/li lidebug_kit は github から最新版を codegit clone/code する。/li /ol p参照:/p ul lia href=http://book.cakephp.org/ja/view/1561/Migrating-from-CakePHP-1-2-to-1-3 title=1.2から1.3への移行ガイド :: 付録 :: マニュアル :: 1.3コレクション :: The Cookbook1.2から1.3への移行ガイド :: 付録 :: マニュアル :: 1.3コレクション :: The Cookbook/a/li /ul
p初期データをマイグレーションでRailsアプリケーションにぶっ込んでみた。後からいちいち手入力するのめんどいし、マイグレーションでデータをロードしとけば、本番環境でうごかすときも coderake db:migrate/code で初期データは入るはずだから楽ちんかなと思って。/p p結果的には無事データをロード出来たんだけど、YAMLの書式が分かってなくて、結局丸一日時間を費やしてしまった。大したデータ量じゃなかったから下手するとちまちま手入力するのと変わらないくらい時間かかったかも。/p div class=highlightprecode class=yamlspan class=l-Scalar-Plainhoge/spanspan class=p-Indicator:/span span class=c1#アイテムの名前/span span class=l-Scalar-Plainid/spanspan class=p-Indicator:/span span class=l-Scalar-Plain1/span span class=l-Scalar-Plainname/spanspan class=p-Indicator:/span span class=squot;hogequot;/span span class=l-Scalar-Plainaddress/spanspan class=p-Indicator:/span span class=squot;ホゲ県ホゲ村ホゲホゲquot;/span span class=l-Scalar-Plainfuga/spanspan class=p-Indicator:/span span class=l-Scalar-Plainid/spanspan class=p-Indicator:/span span class=l-Scalar-Plain2/span span class=l-Scalar-Plainname/spanspan class=p-Indicator:/span span class=squot;fugaquot;/span span class=l-Scalar-Plainaddress/spanspan class=p-Indicator:/span span class=squot;ホゲ県ホゲ村フガフガquot;/span /code/pre /div pとかやんなきゃいけなかったんだけど、YAMLの書き方が分かってなくて、/p div class=highlightprecode class=yamlspan class=l-Scalar-Plainhoge/spanspan class=p-Indicator:/span span class=l-Scalar-Plainid/spanspan class=p-Indicator:/span span class=l-Scalar-Plain1/span span class=l-Scalar-Plainname/spanspan class=p-Indicator:/span span class=squot;hogequot;/span span class=l-Scalar-Plainaddress/spanspan class=p-Indicator:/span span class=squot;ホゲ県ホゲ村ホゲホゲquot;/span span class=l-Scalar-Plainid/spanspan class=p-Indicator:/span span class=l-Scalar-Plain2/span span class=l-Scalar-Plainname/spanspan class=p-Indicator:/span span class=squot;fugaquot;/span span class=l-Scalar-Plainaddress/spanspan class=p-Indicator:/span span class=squot;ホゲ県ホゲ村フガフガquot;/span /code/pre /div pとか書いてた。どっちも hoge県 に分類されるんでこんなんでいいだろ、みたいなノリ。しかしこれはやっぱり文書の構造がおかしい。これをロードしてみると、 id=2 のものしかロードされなかった。/p p結局、拾ってきた コードを参考にして/p div class=highlightprecode class=rubyspan class=nbrequire/span span class=s1#39;yaml#39;/span span class=nbrequire/span span class=s1#39;pp#39;/span span class=ndata/span span class=o=/span span class=noYAML/spanspan class=o./spanspan class=nload_file/spanspan class=p(/spanspan class=s1#39;hoge.yml#39;/spanspan class=p)/span span class=npp/span span class=ndata/span /code/pre /div pみたいなやつを書いて、読み込まれる配列の構造を確認しながらYAMLを書いたところうまくいった。/p
p『RailsによるアジャイルWebアプリケーション開発 第三版』をまだちまちま読んでる。いまActiveRecordのリレーションシップのところ。全然分からなくて全然進まない。もうRails 3.0が出そうだというのに。またろくすっぽ技術書を読まないうちに化石になっちゃいそうだよ。バカはつらいよ。/p
p一個前の記事(a href=http://tech.portalshit.net/2010/06/25/i-realized-php-is-crap/ title=Rubyがエレガントだって言われるのがわかってきたような気がする \| tech.portalshit.net - CakePHP, Rails, JavaScriptRubyがエレガントだって言われるのがわかってきたような気がする | tech.portalshit.net - CakePHP, Rails, JavaScript/a)をcxxさんに添削してもらったところ、Rubyの方のコードには問題があったらしい。Rubyでは変数を宣言だけして終わりみたいな初期化をしちゃダメだそうで、必ず何かを代入しないといけないらしい。/p pそういうわけで正しくは、/p div class=highlightprecode class=rubyspan class=kclass/span span class=ncHoge/span span class=kdef/span span class=nfinitialize/span span class=vi@a/span span class=o=/span span class=s2quot;quot;/span span class=kend/span span class=kdef/span span class=nfhoge/span span class=vi@a/span span class=o=/span span class=s2quot;hogehogequot;/span span class=kend/span span class=kend/span span class=nfuga/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nnew/span span class=nbputs/span span class=nfuga/spanspan class=o./spanspan class=nhoge/span /code/pre /div pと書くそうです。/p pところでなんで自分は前回、 code@a/code というインスタンス変数を使ったのかがよく分からない。Railsでコードを書いていて、Controllerで定義した変数をViewで使うときにインスタンス変数を使うので、そういう風に思い込んでいるのかな。上のコードでは別にインスタンス変数を使う必要はなくて、/p div class=highlightprecode class=rubyspan class=kclass/span span class=ncHoge/span span class=kdef/span span class=nfinitialize/span span class=na/span span class=o=/span span class=s2quot;quot;/span span class=kend/span span class=kdef/span span class=nfhoge/span span class=na/span span class=o=/span span class=s2quot;hogehogequot;/span span class=kend/span span class=kend/span span class=nfuga/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nnew/span span class=nbputs/span span class=nfuga/spanspan class=o./spanspan class=nhoge/span /code/pre /div pでも同じ結果を出力しますね。/p pインスタンス変数と普通の変数の違いが分かってなかったので、たのしいRuby(第2版)を開いて復習してみたところ、以下のような記述があった。(たのしいRuby 第2版 pp.123-124)/p blockquote pcode@/code で始まる変数は emインスタンス変数/em といいます。ローカル変数とは違って、このメソッドを抜けてもその値は保存されますが、インスタンスごとに違う値を割り当てられる変数です。(たのしいRuby 第2版 pp.123-124)/p /blockquote pなるほど! 例えば上のコードを引数つきのものに改造したとしましょう。/p div class=highlightprecode class=rubyspan class=kclass/span span class=ncHoge/span span class=kdef/span span class=nfinitialize/spanspan class=p(/spanspan class=nb/spanspan class=o=/spanspan class=s2quot;quot;/spanspan class=p)/span span class=vi@a/span span class=o=/span span class=nb/span span class=kend/span span class=kdef/span span class=nfhoge/span span class=nbprint/span span class=vi@a/spanspan class=p,/span span class=s2quot;/spanspan class=se\n/spanspan class=s2quot;/span span class=kend/span span class=kend/span span class=nfuga/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nnew/spanspan class=p(/spanspan class=s2quot;Fugaquot;/spanspan class=p)/span span class=npiyo/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nnew/spanspan class=p(/spanspan class=s2quot;Piyoquot;/spanspan class=p)/span span class=nfuga/spanspan class=o./spanspan class=nhoge/span span class=npiyo/spanspan class=o./spanspan class=nhoge/span /code/pre /div pで、これを実行すると/p div class=highlightprecode class=consolespan class=goFuga/span span class=goPiyo/span /code/pre /div pと表示される。こんな感じで、一つのクラスから複数のインスタンスを生成するときに使うのがインスタンス変数って理解でオーケーなのかなと思います。/p
p「PHPは汚い、Rubyはきれい」とかそういう言説の意味が昔は分からなかったんだけど、昨日今日、久々にCakePHPで作ったサイトのメンテナンスをしてて「PHP、確かにきちゃないわ」と思った。/p pオブジェクト指向っぽい何がしかのコードをPHPで書いてみる。/p div class=highlightprecode class=phpspan class=cplt;?php/span span class=kclass/span span class=ncHoge/span span class=p{/span span class=kvar/span span class=nv$a/spanspan class=p;/span span class=kfunction/span span class=nfhoge/spanspan class=p()/span span class=p{/span span class=kreturn/span span class=nv$this/spanspan class=o-gt;/spanspan class=naa/span span class=o=/span span class=s2quot;hogehogequot;/spanspan class=p;/span span class=p}/span span class=p}/span span class=nv$fuga/span span class=o=/span span class=knew/span span class=nxHoge/spanspan class=p();/span span class=kecho/span span class=nv$fuga/spanspan class=o-gt;/spanspan class=nahoge/spanspan class=p();/span span class=cp?gt;/spanspan class=x/span /code/pre /div pつぎにRubyで同じコードを書いてみる。/p div class=highlightprecode class=rubyspan class=kclass/span span class=ncHoge/span span class=vi@a/span span class=kdef/span span class=nfhoge/span span class=vi@a/span span class=o=/span span class=s2quot;hogehogequot;/span span class=kend/span span class=kend/span span class=nfuga/span span class=o=/span span class=noHoge/spanspan class=o./spanspan class=nnew/span span class=nbputs/span span class=nfuga/spanspan class=o./spanspan class=nhoge/span /code/pre /div pまずPHPは中括弧たくさん書かないといけない。これが面倒くさい。中括弧はキーボードでは codeshift + [/code とか codeshift + ]/code とかだから、 codeshift/code の分だけキーボードをたたく回数が増える。実にめんどい。最初はRubyのインデントでブロックを表現するところに慣れなかったけど、慣れたらちまちま中括弧をかかないとダメなPHPにいらいらするようになった。中括弧の閉じ忘れでエラーが出ることとかも多いし。/p pさらにメソッドとか変数へのアクセスもめんどい。Rubyだと code./code でアクセスできるのに、PHPだと code-gt;/code だ。入力するときはキーボードに code-/code と codeshift + ./code と打たなきゃいけない。アホか。Rubyだとキーを一個打つので済むのが、PHPだと三個だ。/p p他にも予約語が長いとか、変数のスコープがおかしいんじゃねとか、Rubyを触る前は分からなかったPHPの変態的なところが目につくようになってきた。/p pPHPちゃん、僕もう疲れたよ(特にCakePHPの配列地獄)。/p
pRailsアプリケーションでMarkdownを使いたと思った。(Markdown大好きっ子なので)/p p調べてみたところ、 a href=http://deveiate.org/projects/BlueCloth title=BlueClothBlueCloth/a というライブラリを使うといいらしい。/p pこれはRailsのプラグインではないのでgemでインストール。/p div class=highlightprecode class=consolespan class=gp$/span sudo gem install bluecloth /code/pre /div pその後viewで/p div class=highlightprecode class=rhtmlspan class=cplt;%=/span span class=nmarkdwon/spanspan class=p(/spanspan class=vi@item/spanspan class=o./spanspan class=ntext/spanspan class=p)/span span class=cp%gt;/span /code/pre /div pとか書けばいい。/p pしかしなんも設定しない状態だとRailsアプリケーションはBlueClothを読み込まないので、config/environment.rbに/p div class=highlightprecode class=rubyspan class=nconfig/spanspan class=o./spanspan class=ngem/span span class=s2quot;blueclothquot;/span /code/pre /div pと書いてやる。するとめでたくMarkdownが使えるようになる。/p
pXREAでRailsを使おうと思っていろいろ調べてみた。Railsは coderake rails:freeze:gems/code してアップロードすればオッケーらしいんだけど、RubyGemsはインストールしないといけないみたい。ところがネットに乗ってる情報を参考にインストールしてみたけど全然うまくいかなかった。指示通りにやってるんだけどパスが通らないのか、インストールしても ‘rubygemsをrequireできねーぞゴラ!’ みたいなエラーが出る。/p pcode.profile/code で記述した codeGEM_HOME/code や codeRUBY_LIB/code のパスは間違ってないと思うんだけど、何回やっても code$HOME/lib//code 直下にRubyGems系のファイルが展開されてしまう。これがエラーの原因っぽい。しょうがないので力業で codeguantlet_rubygems.rb, rbconfig/ rubygems/ rubygems.rb, ubygems.rb/code を code$HOME/lib/ruby/site_ruby/1.8/code に移動させた。その後 codesource ~/.profile/code して適当な場所で codegem -v/code してみたところ、ちゃんと code1.3.5/code と表示された。/p p蛇足だけど最初、RubyGems 1.3.7をインストールしようとしたら、利用予定地のサーバーのRubyのバージョンが1.8.5なためにインストールできなかった。そういうわけでRubyGemsは1.3.5を入れた。/p pあとRubyGemsが入ったからといってシェルで codegem install rails/code とかやってもプロセスを codekill/code されるっぽいのでよい子のみなさんは必要な gem は自分のパソコンでインストールしてからアップロードした方がよさげです。/p
pCakePHPで作ってたプロジェクトのDBのフィールド名にスペルミスを発見したので( codelongitude/code を codelongtitude/code としていた)、それを修正するためにDBの構造をいじった。このとき、Cakeは普通にやってたらSchemaとかの概念に触れる機会がないことに気がついて急に怖くなった(ここんとこRailsばっかり触っていたので)。いや、CakePHPにもSchemaの概念はあるんだけど、普通にサイト作るだけだったら世話になる機会がない。というか俺がCakeの底本にしてた公式ガイドにSchemaの項目がない!/p pこれじゃあgitとかでバージョン管理しててもDBの論理構造が置いてけぼりになって、分散管理とかできないじゃん。SQLite使ってたらバイナリファイルをgitでtrackすればまぁ分散開発でけそうだけど、MySQLとかだったら死ぬよね。/p p確かにCakePHPでサイト作るのは楽だったし早かった。ほぼ何もできない状態の自分が数ヶ月でCMS作れたのはCakePHPのおかげなんだけど、CakePHPは何でもテケトーな感じがする。対してRailsは厳格だ。楽するためのフレームワークというより、よりStrictにサイトを構築するためのフレームワークという感じがする。だから慣れるまでは時間がかかる面があるのは否めないんだけど、SchemaにしろTestにしろ、Railsやってて勉強になることはたくさんあります。はやく皆と同じようにrailsの手術を受けたい。/p
pこのブログのCMSをMephistoからa href=http://github.com/mojombo/jekyll title=mojombo's jekyll at master - GitHubjekyll/aに変えてみた。/p pMephistoは公式サイトつながらないし、Mephisto使ってた外国のGeek連中がここ一年くらいでこぞってJekyllに移行してるみたいなのでこのビッグウェーブに乗ってみた。/p h3 id=jekyll--cmsJekyll = 静的CMS/h3 pしばらくJekyllの使い方が分からなくて格闘してたけど、やっと使い方が分かった。これは静的なCMSであって動的なCMSではない。Movable Typeに似てる。それをGeekなスタイルでやる感じ。/p h3 id=rubyRubyが入ってるサーバーはいらない/h3 pコメント機能とかはないのでサーバーでRubyが動く必要はナッシング。DBも使わないのでMySQLの設定とかSQL分との格闘も必要ナッシング。コメント欄が欲しい場合は a href=http://disqus.com/overview/ title=DISQUS \| OverviewDISQUS/a とかに外注すればOK。/p pちょっと話題がずれるけど、DISQUSって便利そうですよね。他人のブログにコメント書いたあとってそのコントロール権みたいのはブログの持ち主に移行するけど、DISQUSみたいなサービスを利用すればコメントを書いた本人が過去の自分のコメントをトラックしやすくなる。ブログ主にしたってスパム対策とかもやりやすくなる。自前で自分のブログにコメント欄を持つって時代は終わったのかもね。いまはTwitterとかもあるし。/p h3 id=mephistoMephistoからの移行について/h3 pJekyllのgithubのwikiに移行方法が載っけてあるけど(a href=http://wiki.github.com/mojombo/jekyll/blog-migrations title=Blog Migrations - jekyll - GitHubBlog Migrations - jekyll - GitHub/a)、これわかりにくい。というかMephistoをMySQLで運用してないとスクリプトをそのまんまでは利用できない。結果から書くと僕はMephistoはSQLite3で運用してたので移行スクリプトを使えなかった。/p p一応MephistoのDBをSQLite3からMySQLに変更してコンバートすることも試してみたけど、DreamHost上では codegem install mysqlplus/code が codesudo/code 権限がないために実行できず(なぜかユーザーディレクトリへのインストールもはねられる)、ローカルのMacBook上ではActiveRecordとかその辺でエラーが出て(MephistoはRails 2.2.2以下じゃないと動かないみたい)、Railsのバージョンを下げるとかも試してみたんだけどエラーが出続けるので諦めてしまった。/p pそういうわけでして、記事数が16本と少なかったこともあり、ちまちま手書きでMephistoからJekyllに移行しました。/p pコメント欄の設置(DISQUSを利用)とかフィードの生成とかカテゴリーの表示とかができてないけど、暇を見つけていじっていく予定です。/p h3 id=jekyll全般的なJekyllの使用感/h3 pDBいらずだしシンプルでいいっすわ。XML-RPCとかAPIを使ってどうのこうのとかいった機能はないけど、テキストファイルをしこしこ書いて、 .markdown か .textile みたいな拡張子で保存して、 codejekyll/code コマンドを実行するだけでhtmlファイルが code_site/code ディレクトリに生成されて、これをアップロードするだけ。この手順を自動化するシェルスクリプト(a href=http://github.com/henrik/henrik.nyh.se/blob/master/tasks/deploy title=tasks/deploy at master from henrik's henrik.nyh.se - GitHubtasks/deploy at master from henrik’s henrik.nyh.se - GitHub/a)も公開されているので、これを使えばectoとか使うのと変わらん感じでお手軽にブログ記事を投稿できます。/p pTerminalからコマンドライン打つの好きな人とか、軽くてシンプルなブログを求めてる人にはうってつけだと思いますね。/p
pirbが素晴らしい! 惚れた!! PHPとかクソ!!!/p
pポータルシットに前も書いたけど、CakePHPの命名規約ではDBにusersというテーブルがあれば、モデルクラスにUser、コントローラークラスにUsersController、viewsディレクトリにusersっていうのが存在するのを前提とする。これに慣れてしまっているので、Railsのやり方にはなんか慣れない。ModelでPeople、コントローラーでUsersControllerとしてても問題ナッシングなわけだ。むしろRailsではこういうのが普通? Rails使っててCakeをちょこっと触った人のブログにこういう感想があった。/p blockquote cite=http://rails.takeda-soft.jp/blog/show/190 title=Blog-side CakePHP わかりずらい3点 h3コントロールとモデルが密すぎる。/h3 pCakePHPは、コントロール名とモデル名が密接すぎる関連を持っています。PostsControllerというコントロールを作ったら、必ずPostというモデルが存在しないと「モデルが見つからないエラー」になる。/p citea href=http://rails.takeda-soft.jp/blog/show/190 title=Blog-side CakePHP わかりずらい3点Blog-side CakePHP わかりずらい3点/a/cite /blockquote pふむふむ〜、ナルホディウスですぞ〜!!!/p p確かにCakePHPはモデルとコントローラーがガチガチになってて、あるコントローラーが他のモデルクラスにアクセスするときはいちいち/p div class=highlightprecode class=phpspan class=x$use = array(quot;Hogequot;);/span /code/pre /div pとかしなきゃいけなかった。/p p最初の頃はモデル、コントローラー、ビューですべてが一対一に対応してるのですんなりMVCの流れを理解できたんだけど、今にしても思えばこういう考え方はすべてのコントローラーに対応するモデル(つまりDBテーブル)がなければならないというしがらみというか束縛を生じさせる。これでは自由な発想で開発できないし、下手をすると一つのコントローラークラスに大量にメソッドを書いてしまったりして、非常にメンテナンス性の良くないコードを量産してしまう公算がある。本当は機能ごとに細かくクラスは分けた方がいいはずだし、メソッドが一つしかないコントローラークラスがあっても良いはずだ。/p pそういうわけで、はやくこの辺のCake流の思い込みを排除して皆と同じようにrailsの手術を受けたいです。/p
pなんじゃそれ! 『Railsによるアジャイル〜』の15章 P239〜P240を読んでいてクリヴィッツテンギョウ!!! codeapp/controllers/admin/book_controller.rb/code ということができるらしい! んで、そのときのクラス宣言は/p div class=highlightprecode class=rubyspan class=kclass/span span class=ncAdmin/spanspan class=o::/spanspan class=noBookController/span span class=olt;/span span class=noActionController/spanspan class=o::/spanspan class=noBase/span /code/pre /div pとなるらしい! 変態だ!! ぜったい変態だ!!!/p
pCakePHPはなんも考えなくてもテキトーにやってたらサイトできてたんだけど、Railsはそんな風にはやらしてもらえない。Railsのサイト作んの自体の効率性が悪い訳ではもちろんないんだけど、レールに乗るためにはそれなりに知っとかなきゃいけないことが多い感じ。『Railsによるアジャイル〜』はいま14章まで読んだ。14章はテストの章だったんだけど、初めてテストに触れた感じ。CakePHP 1.2の公式ガイドにもテストについての章はあったけど、後ろの方でおまけみたいな感じだったから飛ばしちゃってた。たまたま先月の頭に買ってた『WEB + DB Press 56』がRubyでのテストを紹介してて、そこを読みながら14章のコードを写経していったけど、わりと早い段階でテストの重要性が説いてあって、アジャイル本はしっかりしてるわと思った。/p
pなんか a href=http://mephistoblog.com/Mephistoの公式サイト/a 死んでるし、a href=http://jekyllrb.com/jekyll/a に変えようかなと思ってるんだけど、 a href=http://wiki.github.com/mojombo/jekyll/blog-migrations移行ガイド/a の通りにやってもうまくいかない。/p
pこの前大阪で第二回アメ村ブルゾンの会をやったんですけど、そこで日夜delネットストーキング/delプログラミングにいそしんでおられる皆さんとお会いして、TwitterのStreaming APIの使い方を教えてもらいました。なんか自分でやろうとしてたんだけど、全然見当違いなところを見ていたみたいで、僕もStreaming APIでネットストーキングできるようになりました。pokutunaさんにもらったコードと “Twitter Streaming APIをRubyで試してみる - しばそんノート”:http://d.hatena.ne.jp/shibason/20090816/1250405491 を参考に、以下のような感じにしてみました。/p div class=highlightprecode class=rubyspan class=c1#!/usr/bin/env ruby/span span class=c1# coding: utf-8/span span class=nbrequire/span span class=s1#39;net/http#39;/span span class=nbrequire/span span class=s1#39;uri#39;/span span class=nbrequire/span span class=s1#39;rubygems#39;/span span class=nbrequire/span span class=s1#39;json#39;/span span class=noUSERNAME/span span class=o=/span span class=s1#39;morygonzalez#39;/span span class=noPASSWORD/span span class=o=/span span class=s1#39;***#39;/span span class=nuri/span span class=o=/span span class=noURI/spanspan class=o./spanspan class=nparse/spanspan class=p(/spanspan class=s1#39;http://chirpstream.twitter.com/2b/user.json#39;/spanspan class=p)/span span class=kbegin/span span class=noNet/spanspan class=o::/spanspan class=noHTTP/spanspan class=o./spanspan class=nstart/spanspan class=p(/spanspan class=nuri/spanspan class=o./spanspan class=nhost/spanspan class=p,/span span class=nuri/spanspan class=o./spanspan class=nport/spanspan class=p)/span span class=kdo/span span class=o|/spanspan class=nhttp/spanspan class=o|/span span class=nrequest/span span class=o=/span span class=noNet/spanspan class=o::/spanspan class=noHTTP/spanspan class=o::/spanspan class=noGet/spanspan class=o./spanspan class=nnew/spanspan class=p(/spanspan class=nuri/spanspan class=o./spanspan class=nrequest_uri/spanspan class=p)/span span class=nrequest/spanspan class=o./spanspan class=nbasic_auth/spanspan class=p(/spanspan class=noUSERNAME/spanspan class=p,/span span class=noPASSWORD/spanspan class=p)/span span class=nhttp/spanspan class=o./spanspan class=nrequest/spanspan class=p(/spanspan class=nrequest/spanspan class=p)/span span class=kdo/span span class=o|/spanspan class=nresponse/spanspan class=o|/span span class=kraise/span span class=s1#39;Response is not chunked#39;/span span class=kunless/span span class=nresponse/spanspan class=o./spanspan class=nchunked?/span span class=nresponse/spanspan class=o./spanspan class=nread_body/span span class=kdo/span span class=o|/spanspan class=nchunk/spanspan class=o|/span span class=c1#空行は無視/span span class=nstatus/span span class=o=/span span class=noJSON/spanspan class=o./spanspan class=nparse/spanspan class=p(/spanspan class=nchunk/spanspan class=p)/span span class=krescue/span span class=knext/span span class=c1#eventを含まないものは無視/span span class=knext/span span class=kunless/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;event#39;/spanspan class=o]/span span class=nsource/span span class=o=/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;source#39;/spanspan class=o]/span span class=kif/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;target_object#39;/spanspan class=o]/span span class=ntarget_obj/span span class=o=/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;target_object#39;/spanspan class=o]/span span class=ntarget_user/span span class=o=/span span class=ntarget_obj/spanspan class=o[/spanspan class=s1#39;user#39;/spanspan class=o]/span span class=nbputs/span span class=s2quot;/spanspan class=si#{/spanspan class=nstatus/spanspan class=o[/spanspan class=s1#39;event#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2: /spanspan class=si#{/spanspan class=nsource/spanspan class=o[/spanspan class=s1#39;screen_name#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2 -amp;gt; /spanspan class=si#{/spanspan class=ntarget_user/spanspan class=o[/spanspan class=s1#39;screen_name#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2: /spanspan class=si#{/spanspan class=ntarget_obj/spanspan class=o[/spanspan class=s1#39;text#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2quot;/span span class=kelsif/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;target#39;/spanspan class=o]/span span class=ntarget/span span class=o=/span span class=nstatus/spanspan class=o[/spanspan class=s1#39;target#39;/spanspan class=o]/span span class=nbputs/span span class=s2quot;/spanspan class=si#{/spanspan class=nstatus/spanspan class=o[/spanspan class=s1#39;event#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2: /spanspan class=si#{/spanspan class=nsource/spanspan class=o[/spanspan class=s1#39;screen_name#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2 -amp;gt; /spanspan class=si#{/spanspan class=ntarget/spanspan class=o[/spanspan class=s1#39;screen_name#39;/spanspan class=o]/spanspan class=si}/spanspan class=s2quot;/span span class=kend/span span class=kend/span span class=kend/span span class=kend/span span class=krescue/span span class=noTimeout/spanspan class=o::/spanspan class=noError/span span class=o=gt;/span span class=nex/span span class=nbp/span span class=s2quot;amp;lt;-----!!!! Timeout::Error!!!!-----amp;gt;quot;/span span class=kretry/span span class=kend/span /code/pre /div p教えてもらったコードではTweetの内容を垂れ流しにするやつだったんですけど、自分でちょこっといじってTweet以外のステータスを表示するようにしてみた。しかしなんか調子悪いっぽくて、完全にはStreamを取れてないっぽいです。/p pでもまぁ一歩前進したことは確か。Rubyがんばるぜ。/p
pレンタルサーバーみたいな共有サーバーとか codesudo/code 権限のないサーバーで動かしてるRailsアプリケーションを再起動したくなることがある。でもApacheをリスタートする権限がない。じゃあどうするかとググっていたらこういう記事にたどり着いた。/p blockquote pTo restart your rails app do a “ps x” to get the pid of your dispatch.fcgi process(let’s say it’s 1234) then do a “kill 1234”. This will kill the running process and a new one will be automatically spawned and you should now see your changes. citea href=http://forum.dreamhosters.com/3rdparty/77334-How-do-I-restart-rails-app.htmHow do I restart rails app? - DreamHost Forum/a/cite/p /blockquote p要するに codeps x/code でRailsアプリケーションのプロセスIDを調べ、 codekill #pid/code しちゃうというわけ。 codekill/code できんのかなと半信半疑だったけどちゃんとできた。/p p他のレンタルサーバーには当てはまらないかもしれないけどメモっときます。/p
pちょっとCakePHPで作ってるサイトでRSSフィードを配信したいと思ったのでやってみたんだけど、思いの外面倒くさくてびっくりした。『RailsによるアジャイルWebアプリケーション開発』を読みながらRails 2.3.5でRSSフィード作るときは結構簡単だった気がするので、正直これはないわと思った。/p p『Railsによる〜』で作ってるデモプロジェクトのdpeotのコードを見てみると、RSSを配信するときはControllerに以下のように記述し、/p div class=highlightprecode class=ruby span class=nrespond_to/span span class=kdo/span span class=o|/spanspan class=nbformat/spanspan class=o|/span span class=nbformat/spanspan class=o./spanspan class=nhtml/span span class=c1# index.html.erb/span span class=nbformat/spanspan class=o./spanspan class=nxml/span span class=p{/span span class=nrender/span span class=ss:xml/span span class=o=gt;/span span class=vi@products/span span class=p}/span span class=kend/span /code/pre /div pcodeconfig/routes.rb/code に/p div class=highlightprecode class=ruby span class=nmap/spanspan class=o./spanspan class=nconnect/span span class=s1#39;:controller/:action/:id.:format#39;/span /code/pre /div pと書いたあと、RSS用のViewを用意してやるだけだ。ものすごくシンプルで簡単だった。/p pCakePHPで同じことをやるためには以下の手順が必要。/p pa href=http://book.cakephp.org/view/483/Creating-an-RSS-feed-with-the-RssHelperCreating an RSS feed with the RssHelper :: RSS :: Core Helpers :: The Manual :: 1.2 Collection :: The Cookbook/a/p pちょっと面倒くさすぎてやる気にならなかった。どうせいま僕が作ってるサイトなんてRSSリーダー使うような人が見るサイトじゃないし、フィード配信機能の実装はそんなにプライオリティ高くないので他にやることがなくてどうしようもなく暇なときにでもやろう。/p pRailsは最初のとっかかりのハードルは高いけど、使い方を覚えていったらやっぱりCakePHPとかよりも全然簡単かつ高速に開発できる気がする。レールに乗ってる感強い。このMephistoの設置もすごく楽だった。ただTerminalを使い慣れた人や、サーバーにSSHでアクセスできる環境じゃないとRailsアプリケーションを使うのは難しい。CakePHPは反面、全部FTPでアップロードすれば良いのでサーバーに標準的な構成でPHPがインストールされてりゃ環境構築でつまずくことはない。どっちをとるかって話ですよね。/p p僕はファッションの観点からRailsを選びたい。/p
p『Railsによるアジャイル〜』とかのコードはViewの部分がスゲーシンプルで、ロジックがほとんど書いてない。これに慣れると、CakePHPに戻って自分が作ってるウェブアプリを見たときに、Viewに結構ロジックが書いてあって愕然とする。例えばフラグをたてて条件にマッチすれば日付を表示し、マッチしなければ表示しないとかしたいとするじゃないですか。Controllerでそういう設定できなくないけど長くなる。Viewの中に書いてしまったら数行で済むし。/p pだから僕の作ってるCakePHPアプリはMVCとか名ばかりでViewのコード超きたない。入れ子になったif文がたくさんあるし、正規表現で日付の書式変更とかまでやってる。さすがに関数とかは定義してないですけどね。/p pそもそもCake FoundationのCakeBookも結構Viewにロジックが書いてあったりする。というかかなりハードに書いてある。CakePHPってViewとロジックを分離させるのが難しいのかな。/p p加えて、Controllerも結構ひどいことになってる。本当はModelに書くべきことを結構Controllerに書いている気がしないではない。サイト検索のためのメソッドとか200行近くあるし、joinとかしまくり。/p pMVCでロジックとヴューを分離することでデザイナーがViewを触れるようになって分業が進むかもとか思ってたけど、到底そんな状況にないですね。/p
pGitでbranchの効率的な使い方みたいのがよくわからない。/p ul li p実験的な機能をつけたい/p /li li pブランチを分ける(例えば開発用に alternate というブランチを作る)/p /li li p開発する/p /li li p開発完了後、 master にマージ/p /li /ul pみたいな感じかなと思ってた。/p pしかし実際に運用してみると、実験的な機能の実装の他に、日常的にmasterでコードの改良みたいな作業があり、alternateで開発が完了した後にmasterにマージしたら多分コンフリクト起こりまくりになるような気がしてきた。/p pそれで日常メンテみたいな作業はmasterブランチで行い、それをalternateにマージするという手順をとってる。正しい開発方法かどうかはわからないけど、一応alternateブランチもmasterの最新の変更を追跡できる。んでalternateではしこしこ開発を続けて、開発完了時にmasterにマージしても多分派手なコンフリクトは起こらないんじゃないかと思ってますがどうなんでしょう。/p
pこういうコード書いてます。/p div class=highlightprecode class=javascriptspan class=kdfunction/span span class=nxgetAttrName/spanspan class=p(/spanspan class=nxattrObj/spanspan class=p)/span span class=p{/span span class=kdvar/span span class=nxattrName/span span class=o=/span span class=nxattrObj/spanspan class=p./spanspan class=nxfirstChild/spanspan class=p./spanspan class=nxdata/spanspan class=p;/span span class=c1// items = document.getElementsByClassName(#39;item#39;);/span span class=kdvar/span span class=nxitems/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s1#39;li.item#39;/spanspan class=p);/span span class=nx$/spanspan class=p(/spanspan class=nxitems/spanspan class=p)./spanspan class=nxfadeOut/spanspan class=p(/spanspan class=s1#39;slow#39;/spanspan class=p);/span span class=kfor/span span class=p(/spanspan class=kdvar/span span class=nxi/span span class=o=/span span class=mi0/spanspan class=p;/span span class=nxi/span span class=oamp;/spanspan class=nxlt/spanspan class=p;/span span class=nxitems/spanspan class=p./spanspan class=nxlength/spanspan class=p;/span span class=nxi/spanspan class=o++/spanspan class=p)/span span class=p{/span span class=c1// var keywordList = items[i].getElementsByClassName(#39;keyword-list#39;);/span span class=kdvar/span span class=nxkeywordList/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s1#39;.keyword-list#39;/spanspan class=p,/span span class=nxitems/spanspan class=p[/spanspan class=nxi/spanspan class=p]);/span span class=kfor/span span class=p(/spanspan class=kdvar/span span class=nxj/span span class=o=/span span class=mi0/spanspan class=p;/span span class=nxj/span span class=oamp;/spanspan class=nxlt/spanspan class=p;/span span class=nxkeywordList/spanspan class=p./spanspan class=nxlength/spanspan class=p;/span span class=nxj/spanspan class=o++/spanspan class=p)/span span class=p{/span span class=c1//var keywords = keywordList[j].getElementsByTagName(#39;li#39;);/span span class=kdvar/span span class=nxkeywords/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s1#39;li#39;/spanspan class=p,/span span class=nxkeywordList/spanspan class=p[/spanspan class=nxj/spanspan class=p]);/span span class=kfor/span span class=p(/spanspan class=kdvar/span span class=nxk/span span class=o=/span span class=mi0/spanspan class=p;/span span class=nxk/span span class=oamp;/spanspan class=nxlt/spanspan class=p;/span span class=nxkeywords/spanspan class=p./spanspan class=nxlength/spanspan class=p;/span span class=nxk/spanspan class=o++/spanspan class=p)/span span class=p{/span span class=kif/span span class=p(/spanspan class=nxattrName/span span class=o==/span span class=nxkeywords/spanspan class=p[/spanspan class=nxk/spanspan class=p]./spanspan class=nxtextContent/spanspan class=p)/span span class=p{/span span class=nx$/spanspan class=p(/spanspan class=nxitems/spanspan class=p[/spanspan class=nxi/spanspan class=p])./spanspan class=nxfadeIn/spanspan class=p(/spanspan class=s1#39;slow#39;/spanspan class=p);/span span class=p}/span span class=p}/span span class=p}/span span class=p}/span span class=nxgetCurAttr/spanspan class=p(/spanspan class=nxattrName/spanspan class=p);/span span class=p}/span span class=kdfunction/span span class=nxgetCurAttr/spanspan class=p(/spanspan class=nxattrName/spanspan class=p)/span span class=p{/span span class=kdvar/span span class=nxcurAttr/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s2quot;#keySelector li aquot;/spanspan class=p);/span span class=kfor/span span class=p(/spanspan class=kdvar/span span class=nxl/span span class=o=/span span class=mi0/spanspan class=p;/span span class=nxl/span span class=oamp;/spanspan class=nxlt/spanspan class=p;/span span class=nxcurAttr/spanspan class=p./spanspan class=nxlength/spanspan class=p;/span span class=nxl/spanspan class=o++/spanspan class=p)/span span class=p{/span span class=kif/span span class=p(/spanspan class=nx$/spanspan class=p(/spanspan class=nxcurAttr/spanspan class=p[/spanspan class=nxl/spanspan class=p])./spanspan class=nxtext/spanspan class=p()/span span class=o==/span span class=nxattrName/spanspan class=p)/span span class=p{/span span class=nx$/spanspan class=p(/spanspan class=nxcurAttr/spanspan class=p[/spanspan class=nxl/spanspan class=p]./spanspan class=nxparentNode/spanspan class=p)./spanspan class=nxaddClass/spanspan class=p(/spanspan class=s1#39;current-keyword#39;/spanspan class=p);/span span class=p}/span span class=kelse/span span class=p{/span span class=nx$/spanspan class=p(/spanspan class=nxcurAttr/spanspan class=p[/spanspan class=nxl/spanspan class=p]./spanspan class=nxparentNode/spanspan class=p)./spanspan class=nxremoveClass/spanspan class=p(/spanspan class=s1#39;current-keyword#39;/spanspan class=p);/span span class=p}/span span class=p}/span span class=p}/span /code/pre /div pやりたいことは以下のような感じ。/p ol lionclickで codeattrObj/code が codegetAttrName/code に渡される/li liクリックされた文字列を codeattrName/code に格納/li liすべての codeitem/code をjQueryを使って非表示/li licodeitem/code の中の codeul.keyword-list li/code 内のテキストに一致したらjQueryで表示/li /ol pFirefox/Safari/Operaでは問題なく動く。しかしIEが全滅。最初は codegetElementByClassName/code とか使ってるからかと思ってたけど、その辺のやつをコメントアウトしてjQueryセレクタを使ってオブジェクトを取得するようにしてもダメ。なんかループの処理とかが怪しいんじゃないかと思ってる。ループ処理もjQueryに書き換えようかな。/p pブラウザ間の挙動の違いを吸収してくれるライブラリはまじですごいしありがたいのですが、結局IEちゃんでは動かせない。歯がゆいな。/p pサーバーサイドで実装する方法もないではないけど、/p ol liいじる部分が広範囲になりめんどい(新たなバグが発生するかも)/li li大した機能じゃないのに大手術したくない/li liずっとPHPばっかり触ってるのはつまらん/li /ol pなどという理由により期限ぎりぎりまでJavaScriptで粘ってみたいです。/p h3 id=section追記/h3 p“Twitterでcxxさんに教えてもらった”:http://twitter.com/cxx/status/13545498622 んだけど、IEにはtextContetはないそうです。恥ずかしい。/p pそういうわけで/p div class=highlightprecode class=javascriptspan class=kdvar/span span class=nxkeywords/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s1#39;li#39;/spanspan class=p,/span span class=nxkeywordList/spanspan class=p[/spanspan class=nxj/spanspan class=p]);/span /code/pre /div pを/p div class=highlightprecode class=javascriptspan class=kdvar/span span class=nxkeywords/span span class=o=/span span class=nx$/spanspan class=p(/spanspan class=s1#39;li a#39;/spanspan class=p,/span span class=nxkeywordList/spanspan class=p[/spanspan class=nxj/spanspan class=p]);/span /code/pre /div pとし、/p div class=highlightprecode class=javascriptspan class=kif/span span class=p(/spanspan class=nxattrName/span span class=o==/span span class=nxkeywords/spanspan class=p[/spanspan class=nxk/spanspan class=p]./spanspan class=nxtextContent/spanspan class=p)/span /code/pre /div pを/p div class=highlightprecode class=javascriptspan class=kif/span span class=p(/spanspan class=nxattrName/span span class=o==/span span class=nxkeywords/spanspan class=p[/spanspan class=nxk/spanspan class=p]./spanspan class=nxfirstChild/spanspan class=p./spanspan class=nxdata/spanspan class=p)/span /code/pre /div pにしてみたところ、ばっちりIEで動くようになった。/p pcxxさんありがとうございます。今度焼き肉デートしましょう。/p
pポータルシットがクソ重くて、なんか対策ないかなーとか仕事をさぼりながらときどき調べてた。/p pおおよその原因は掴んでいた。それはアクセス解析プラグイン。MySQLのデータ容量がでかくなるとページの表示が遅くなる。アクセス解析プラグインを無効にした状態でページの表示速度はだいたい0.05秒くらいなんだけど、アクセス解析プラグインを有効にすると表示速度は1秒台とかまで悪化する。アクセス解析に使うテーブル( codep_page_analyze/code )をDROPするとまた速さが回復するので時々空にしていた。/p pしかしよくよくアクセス解析プラグインのコードを覗いてみると、ヴュー部分で使っていないSQLクエリが発行されており、このせいでクエリの回数が必要な回数の何倍にもなっていた。ポータルシットのアクセスなんて大したことないんだから、DBのサイズがちょっとでかくなっただけでこんなに遅くなるはずがないのだ。/p pそういうわけで不必要なクエリのトリガーになるコードをコメントアウトしてみた。すると1秒台だった表示速度は0.2秒から0.5秒程度に収まるようになった。しかしそれでもなんか遅く感じる。/p pそれでキャッシュを効かせることにしてみた。使ったのはPecl APC。DreamHostはなんでもやらせてくれるのでほんと助かる。/p pa href=http://wiki.dreamhost.com/Pecl_APCPecl APC - DreamHost/a を見ながらシェルスクリプトをコピペして走らせ、php.iniにAPCの設定を書き加えて終了。僕はPHPのバージョンを5.3.1に上げているのでコピペしたシェルスクリプトのまんまではきちんと入らなかった。最新版のAPC(APC-3.1.3p1)にバージョン情報を書き換えてインストールしたところうまくいった。またDreamHost Wikiではキャッシュファイルのパスが code/home/username/tmp/apc.*XXXXXX*/code だったり code/home/username/tmp/apc.*XXXXX*/code だったりばらついてるけど、Xの数は6個じゃないと500エラーが出るのでご注意を。/p pキャッシュを効かせて見た結果、フッターのPage Generationはあまり変化がないが、体感速度は十分に速くなった。/p
pa href=http://bakery.cakephp.org/articles/view/announcing-cakephp-1-3-0-stableCakePHP 1.3のStableがリリース/a された。 a href=http://book.cakephp.org/view/1561/Migrating-from-CakePHP-1-2-to-1-3JavascriptヘルパーとかAjaxヘルパーが非推奨になってる/a 。かわりにHtmlヘルパーのjsメソッドを使うらしい。 code$html-gt;js('')/code みたいな感じかな。で、Ajax系の処理はjQueryがデフォルトのライブラリになったらしい。Rails 3.0もprotorype.jsに別れを告げたらしいし、自分がJavaScriptのライブラリで遊び始めた頃はjQueryが全盛だったのでいまからprototype.jsの使い方勉強するのかったるかったし、jQuery簡単だしこの進化は大歓迎です。/p pJavascriptヘルパーとAjaxヘルパーが非推奨になった件については、わざわざ別のヘルパーにせんでもいいよなー、という印象は確かに持ってた。Htmlをいじるメソッドは一つのヘルパークラスにまとめてしまった方がすっきりする。1.2.xのときはAjaxヘルパーが使いづらすぎて結局jQueryでAjaxすることもあったし、あまり存在意義を見いだせなかったので良かったんじゃないでしょうか。/p pでも既存のプロジェクトの1.3への移行はめんどくさそうなのでたぶんやんない気がする。新しくCakePHPでなんか作るときは使ってみようと思います。/p
pMephistoでGoogle Analytics使おうと思ってググったら a href=http://www.artweb-design.de/projects/ruby-on-rails-plugin-google-analyticsRuby on Rails Plugin: Google Analytics (blue egg edition) - artweb design/a というのが出てきたので、早速インストールしてみたんだけど動いていないっぽい。/p pMephistoは「rails blog」でググって一番上に出てきたので深く考えもせずにインストールしてしまったんだけど、一年近くバージョンアップされてないし、いまはあんまり活発に開発が行われてるわけじゃないっぽいな。/p h3 id=section追記/h3 p一晩寝て起きたら動いてた。/p
pCakePHPには a href=http://github.com/davidpersson/mediaMedia Plugin/a というのがあって、これがすこぶる便利。画像や文書の他に、動画ファイルまで扱うことができる。PHPではファイルアップロードのところにセキュリティリスクが潜んでいそうなイメージだし、自分のような素人に毛が生えたようなレベルの人間は素直にこういう便利なプラグインを使った方がいい。/p pしかしこのMedia Plugin、設置が少々面倒だ。情報も英語のものも含めて少ない。僕は二つのプロジェクトでこのMedia Pluginを使ったけど、とても設置に苦労した。はまるポイントはいくつかあるんだけど、今日はDBについて書いておこうと思う。/p pMedia Pluginは codeattachments/code というテーブルをつくり、ここにファイルのメタデータを格納していく。これはアプリケーションのルート( codeAPP/code ディレクトリ)で codecake media init/code というコマンドをTerminalで打ってやると(ただし code/cake/console/code にパスを通しておく必要あり)、Bakeのときのような画面が出てきて初期設定をやってくれる( codeapp/config/database.php/code の情報にあわせてテーブルも作ってくれる)。しかしCakePHPのデフォルトDBがMySQLであるためMedia PluginもMySQLを想定しているのか、 codeapp/plugins/media/config/sql/media.sql/code のSQL文を単純に実行してしまうと不具合が生じる。実は僕はここで結構はまってた。僕は全部のプロジェクトでSQLiteを使っているので、単純にこのSQLを実行すると、 codeattachments.id/code のデータ型が codeINT(10)/code とかになってしまい、エラーに遭遇し続けることになってしまった。SQLiteの場合、idカラムのデータ型は codeINTEGER/code でなければならないのだ。/p pこれはMedia Pluginに限らないけど、Convention Over Configuration なフレームワークを使うときは、DBのテーブル名に注意をはらわなければならない。否、先にも書いたとおりそれだけでは不十分で、さらにカラムのデータ型とかも規約に沿ったものにしないと、原因不明の謎のエラーに遭遇して開発が停滞する。おっちょこちょいな人(僕も含めて)はその辺の基本的な部分をおろそかにしない方がいいと思った/p
pなんかTwitterで「最近のポータルシット変わったよね…」とかいう意見を目にするようになったので、パソコンネタだけ隔離して別にブログを始めることにした。使っているCMSはMephisto。Railsの勉強になるかと思って。早速DreamhostへMephistoをインストールしていて躓いてしまったのでちょこっとメモ。/p pとりあえず tech.portalshit.net というサブドメインを用意し、DreamhostのパネルでPassengerのセットアップ。その後SSHでサーバーに接続し、/p div class=highlightprecode class=consolespan class=go $ git clone git://github.com/emk/mephisto.git/span /code/pre /div pしてgithubからプロジェクトをclone。/p pMephistoのインストールにはいくつかgemが必要。Dreamhostには結構たくさんgemがインストールしてあるんだけど、いくつか足りないものがあった。とりあえず設置ディレクトリのルートで/p div class=highlightprecode class=consolespan class=go $ rake gems:install/span /code/pre /div pと打ってみたところ、nokogiriとそれに依存するbrynary-webratが入らなかった。原因を調べてみたところ、xsltのライブラリをダウンロードして、codegem install/code するときにパスを指定してあげる必要があるらしい。xsltのライブラリ自体はPHP5をカスタムインストールしたときに入れてあるので、以下のオプションでインストールした。/p div class=highlightprecode class=consolespan class=go $ gem install nokogiri \/span span class=go --with-xslt-include=/home/morygonzalez/php5/include/ \/span span class=go --with-xslt-lib=/home/morygonzalez/php5/lib//span /code/pre /div p無事インストール成功。その後もう一回 coderake gems:install/code を実行してbrynary-webratも入り、管理ページにアクセスしてみると今度はPassengerのエラーが。これは単純にdatabase.ymlに codedevelopment:/code のDB環境しか記述していなかったこと、 coderake db:bootstrap/code のときに codeRAILS_ENV=production/code をつけていなかったことが原因だった。そういうわけでdatabase.ymlに codeproduction:/code の設定(sqlite3を使用)を書き、/p div class=highlightprecode class=consolespan class=go $ rake db:bootstrap RAILS_ENV=production/span /code/pre /div pですべてのインストール作業完了。いまこうして動いております。/p p今後はここにCakePHPやRails、JavaScript関連のことを書いていこうと思います。できれば一日一ポスト、その日に学んだことを書いていきたいです。/p
Updates
-
リストカット感覚でさくらVPSのUbuntu再起動して二日間くらいNginxが止まったままになってた。
-
Windowsのコマンドプロンプトで "chdir" とか打つ度に地球温暖化が進みそう。
-
ワイフが作ってくれたお弁当うまい。
-
仕事でRailsやると幸せすぎてしょんべんちびりそうになる。
-
真夏に長袖を着た人がいるのが都会で半袖を着た人しかいないのが田舎。
-
やたらSleipnirをすすめてくる人が苦手
-
@kansen00 僕もデブなので洋式派です。
-
@fuba_recorder おすすめの子ども向けアニメ教えて。
-
ピザとスパゲティを一緒に食べると、チャーハンをおかずに白米を食べてた友達のことを思い出す。
-
Junk Do It (@ ジュンク堂書店 福岡店 w/ 2 others) http://4sq.com/nJa5L7
-
パトロール 自警団 違法
-
いまから緊急海水浴したい。
-
タッチの差で和風便器に入らざるを得なくなった人の悲愴を詩にして吟じたい。
-
申し遅れましたが分割金利手数料ジャパネットたかた負担で液晶テレビ買いました。
-
福岡の人月単価、中国に負けつつあるらしいです。
-
振ると充電されるPocket WiFi欲しい。
-
昨日の昼、激安コンビニに行ったら結構小綺麗な格好したサラリーマンも300円くらいで昼飯済まそうとしてて暗い気持ちになった。
-
ヱビスよりうまい麦とホップという液体があるのに本物のビール飲むなんて…
-
ワルだからrailsのpublicディレクトリにphpinfo.phpみたいなファイル置いて遊んでる。
-
pearとかpecl、それ自体がすでにぶっ壊れてる感じがして怖い。
Posts
中学校の図書館にあった覚せい剤の怖さを訴える本の中の「こんな異常行動をする」っていうページのイラストで、若者の集団が公園の砂場の砂にイヤホンジャックを差して「おっ音楽が聞こえる」「嘘つけ!ギャハハ!本当だ」とかやってて「めっちゃたのしそうだな」と思ってうらやましかった
Posts
産經新聞のサイト、縦持ちしたアイパットで見たら縦分割の二段組レイアウトで表示されたけどクソ見にくかった。
>|coffee| でCoffeeScriptに色つくようになった / “アクセス解析で見られるデータを過去30日分に増やしました - はてなブログ開発ブログ”
collect と inject しか使ってない
sqale はわしが育てた / “Sqale - 開発者のためのホスティングサービス【スケール】Ruby on Rails 対応。”
餃子うまい
ぬるい水しか出てこなくてシャワーのあと掃除機みたいなドライヤーで体温取り戻しました。
いなり握った
ダウンローダー直しました / “近デジダウンローダー2.0 - hitode909の日記”
いろんな立場の人からメッセージ来てる
respond_to |format| do ... で CSV を出力する方法
yelpで調べたスシうまい なんか異常な味がする
昭和なんなんでしょうね
Mongoid で簡単に group_by するやつ
かもめ乗ってる
Recent tracks
-
White Sand Interlude by {u'mbid': u'b8e57165-fd9e-4676-b38c-aef2f6cf3344', u'#text': u'Question?'}18 minutes ago
-
Criminal Art Lovers by {u'mbid': u'0294464a-fd47-4709-b85d-9d77aa6e822f', u'#text': u'Northern Portrait'}21 minutes ago
-
Run Run Run by {u'mbid': u'27acb789-8616-4b78-a140-3b47d9299c6b', u'#text': u'Curly Giraffe'}30 minutes ago
-
Highway 8 by {u'mbid': u'', u'#text': u'Clockart'}4 hours ago
-
Tangerines & Unicorns by {u'mbid': u'fe8134d4-44fc-4eac-8e00-fb1dc1e996b6', u'#text': u'Polock'}5 hours ago
-
The Windmills Of Your Mind by {u'mbid': u'', u'#text': u'Oscar Peterson Trio'}5 hours ago
-
Is My World by {u'mbid': u'', u'#text': u'Olive Oil'}5 hours ago
-
Too Fast by {u'mbid': u'ce487d5c-c0cf-4da4-a59f-dab8d7f65aee', u'#text': u'Maren & Montauk'}5 hours ago
-
消火栓 by {u'mbid': u'', u'#text': u'\u30ad\u30a8\u308b\u30de\u30ad\u30e5\u30a6'}5 hours ago
-
It's Over by {u'mbid': u'139a00a8-6b21-47c3-9315-60ac5ab2c715', u'#text': u'Bobby Caldwell'}6 hours ago
Top artists
Top tracks
-
109 plays
-
104 plays
-
103 plays
-
97 plays
-
94 plays
-
79 plays
-
73 plays
-
72 plays
-
70 plays
-
70 plays
-
64 plays
-
64 plays
-
58 plays
-
58 plays
-
58 plays
-
57 plays
-
53 plays
-
52 plays
-
52 plays
-
Supersonic by Oasis51 plays
-
51 plays
-
51 plays
-
51 plays
-
50 plays
-
49 plays
-
48 plays
-
48 plays
-
48 plays
-
47 plays
-
46 plays
-
45 plays
-
45 plays
-
42 plays
-
41 plays
-
41 plays
-
39 plays
-
Us by Regina Spektor39 plays
-
39 plays
-
39 plays
-
39 plays
-
39 plays
-
38 plays
-
38 plays
-
38 plays
-
38 plays
-
38 plays
-
37 plays
-
37 plays
-
37 plays
-
May by Brittle Stars36 plays
Latest checkin
-
@地下鉄 天神駅 (Tenjin Sta.) (K08) (中央区天神1-11)25 hours ago in 福岡市, 福岡県
Badges
Checkin history
-
@地下鉄 天神駅 (Tenjin Sta.) (K08) (中央区天神1-11)25 hours ago
-
@TOWER RECORDS 福岡店 (中央区天神2-11-2)26 hours ago
-
@新天町 (中央区天神2丁目)26 hours ago
-
@天神プライム (日本)37 hours ago
-
@新天町 (中央区天神2丁目)37 hours ago
-
@カフェ ガレリア (CAFE galleria) (大名2-1-50)2 days ago
-
@天神プライム (日本)2 days ago
-
@新天町 (中央区天神2丁目)2 days ago
-
@地下鉄 天神駅 (Tenjin Sta.) (K08) (中央区天神1-11)2 days ago
-
@地下鉄 天神駅 (Tenjin Sta.) (K08) (中央区天神1-11)2 days ago
-
@喫茶プリンス (天神2丁目10-13)3 days ago
-
@天神プライム (日本)3 days ago
-
@新天町 (中央区天神2丁目)3 days ago
-
@地下鉄 天神駅 (Tenjin Sta.) (K08) (中央区天神1-11)4 days ago
-
@新天町 (中央区天神2丁目)4 days ago
-
@新天町 (中央区天神2丁目)4 days ago
-
@天神プライム (日本)4 days ago
-
@新天町 (中央区天神2丁目)4 days ago
-
@ドラッグセガミ 福岡天神本店 (中央区天神2-8-49)5 days ago
-
@カフェ ガレリア (CAFE galleria) (大名2-1-50)5 days ago