| @労働

こういう会社で働けたら幸せだろうなと思います。

理想の会社

  1. Gitでソースコード管理している。
  2. 会社のGithubアカウントがある。
  3. 外部に公開されている技術ブログがある。
  4. IDEよりVimやEmacsを使うことが奨励されている。
  5. 社員が勉強会に参加することを奨励している。
  6. オープンソースコミュニティに貢献している。
  7. 音楽を聞きながら仕事できる。
  8. Rubyで開発できる。
  9. 会議が短い。
  10. アジャイル開発を実践している。
  11. テストコードがある。
  12. エンジニアは全員ノートパソコンで開発して、好きかってに席を替わってペアプログラミングとかやってる。
  13. MacとLinuxしかない。
  14. 優秀なデザイナーがいる。
  15. でかい本屋が近くにある。
  16. プログラムを書くことが好きな人たちが集まっている。
  17. SEという肩書きの人がいない。
  18. 大所帯でない。
  19. 金曜の夜はみんなはやく帰る。
  20. イスに金をかけている。
  21. 社員がfoursquareで会社のMayorの座を競い合っている。

| @Mac/iPhone

Google Chromeの拡張機能に、Chrome Keyconfig ってのがあります。これはMinibuffer + LDRizeとまではいかないまでも似たような機能を提供してくれるエクステンションで便利に使っていたんですけど、最近、一旦Google Chromeを終了すると前回使用時に変更した拡張機能設定項目の内容が読み込まれないという不具合が発生するようになり、非常に不便でした。

Chrome KeyconfigとTberarelooの組み合わせで、Firefox + Greasemonkey + Minibuffer + LDRize + Reblog Command とほぼ同様の快適さでTumblrが閲覧できるようになるわけでして(Google ChromeでFirefoxのようなReblogしまくれる環境を構築する - Syoichi's Tumblr)、毎回Tumblr閲覧時にChrome Keyconfigの設定画面を開いて設定を変更するのは面倒くさいこと極まりありませんでした。

ちょっと調べてみたところ、以下のような原因でChrome Keyconfigの設定項目の変更内容が反映されないようです。すなわち、Chrome Keyconfigの設定項目の内容を保存しているDBの "ItemTable" というテーブルに "Config" という key を持つレコードと "Keyconfig" という key を持つレコードがあって、設定項目の変更内容は "Keyconfig" に保存されるけどChrome KeyconfigはGoogle Chromeを一旦終了して再起動すると "Config" の方を読みに行っちゃう、ということらしいです。

したがってChrome Keyconfigの設定内容を保存しているSQLite3のDBを直接開いて編集してやればよいわけですね。"Config" という key を持つレコードの value を "Keyconfig" の値で上書きしてやればよい。上記リンク先ではWindows環境で、SQLiteを編集するソフトを使って値を変更する方法が紹介されていますが、Macでは以下のコマンドで行けます。

cd ~/Library/Application Support/Google/Chrome/Default/Local Storage  
sqlite3 chrome-extension_okneonigbfnolfkmfgjmaeniipdjkgkl_0.localstorage "update ItemTable set value = (select value from ItemTable where key = 'Config') where key = 'Keyconfig';"
{: .console }

よろしければお試し下さい。

| @技術/プログラミング

暇だったので自動で特定のユーザーを延々favし続けるスクリプトを書いた。

ヒトデ君が書いた hitode909/user-stream-receiver - GitHubRuby+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 ストーキングしたい相手のユーザー名

| @技術/プログラミング

ポータルシットを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 の値もリセットされる。人畜無害なテストコード万歳。

| @Mac/iPhone

youpyさん作のiTunesで聞いてる曲のレートが5だったらLast.fmに "Love" を送信してくれるやつを試してみようとした。cronで2分間隔とかで回して使うやつ。

なんで二年近く前のやつを今頃使ってみようとしたのかというと、二年前はRubyとかUnixのことが全然分かんなくてブックマークしただけだったから。いまは多少はRuby分かるし、crontabの使い方も分かるので、いましかないと思ったわけです。

git clone git://gist.github.com/58251.git
cd 58251
ruby love.rb

初回起動時にはLast.fmのAPIキーやTokenを入力するようにコンソールにメッセージが表示される。その後こういうエラーが出てしまった。

/Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle: dlopen(/Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle, 9): no suitable image found.  Did find: (LoadError)
  /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle: no matching architecture in universal wrapper - /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:29:in `require'
  from /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/rbosa.rb:29
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:34:in `gem_original_require'
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:34:in `require'
  from love.rb:71:in `initialize'
  from love.rb:61:in `new'
  from love.rb:61:in `get_instance'
  from love.rb:34:in `main'
  from love.rb:206

なんかアーキテクチャが違うとかそれ系のエラーメッセージが出ている模様。そもそもRubyOSAって何なんだろうと思って調べてみたら、以下にたどり着いた。

なるほど、Appleが用意してるRubyからMac OS Xのイベントとかを管理できるようにするやつか。RubyをAppleScript的な使い方が出来るようにするらしい。Snow Leopard発売前の2007年に出たVersion 0.4.0で開発止まってるみたいだし、64bit化したSnow Leopardでは使えないってことなんだろうか。いや、64bit化する前のMacBook黒からTimeMachineでデータを引き継いでるから、アーキテクチャに合わないRubyOSAが入ったままになってるのかもしんない。「10.6 Snow Leopard と RubyOSA のインストール - Numata Designed Factory」 という記事を参考に、RubyOSAを入れ直してみることにした。

svn checkout svn://rubyforge.org/var/svn/rubyosa
cd rubyosa/trunk
cat src/rbosa.c | (rm src/rbosa.c; sed "s/c ID/c RB_ID/g" > src/rbosa.c)
ruby extconf.rb
make
sudo make install
sudo make install-extras

インストール後、再度 ruby love.rb を実行してみた。しかし今度は以下のようなエラーが出る。

/Library/Ruby/Site/1.8/rbosa.rb:470: warning: Passing no parameters to XML::Parser.new is deprecated.  Pass an instance of XML::Parser::Context instead.
XML::Parser#string is deprecated.  Use XML::Parser.string instead
/Library/Ruby/Site/1.8/rbosa.rb:558:in `__send_event__': Cannot send Apple Event 'coregetd' : procNotFound (-600) (RuntimeError)
  from /Library/Ruby/Site/1.8/rbosa.rb:558:in `player_state'
  from love.rb:77:in `playing?'
  from love.rb:36:in `main'
  from love.rb:206

どうも古いバージョンの libxml を使わないとエラーが出るらしい。今度は「RubyOSA 0.4.0を使おうとしたのですが、Bus Errorが発生 - Watsonのメモ」という記事を参考に以下のようにした。

diff /Library/Ruby/Site/1.8/rbosa.rb /Library/Ruby/Site/1.8/rbosa.rb.org
39c39
<   gem 'xml/libxml', '= 0.3.8.4'
---
>   require 'xml/libxml'

とりあえず、irbでrbosaをrequireしてもエラーは出なくなった。

irb -r rbosa
>> itunes = OSA.app('iTunes')
=> <OSA::ITunes::Application:0x10173bb38 desc="'sign'($6B6F6F68$)">

iTunesでレートは★★★★★だけどLast.fmで "Love" マークが付いてない曲を再生しながら、もう一度 ruby love.rb してみたところ、 {"status"=>"ok"} が返ってきた。ちゃんとLast.fmで "Love" されてた。iTunesで音楽を聴いてるときにcronで回してあげれば常にレート5の曲をLast.fmで "Love" してくれるようになる。Launch Daemon化とかはやり方が分からないのでそのうち調べる。

| @写真

凍りついた窓 2010-12-31

雪 2010-12-31

| @WWW

ちょっと前の本だけど、『Webを支える技術』をいま読んでます。

HTTPの話とか、毎日使ってる技術のことを知らなくて、いちいち感動しながら読んでるんですけど、中でも興味深かったのがURIの話。56ページの、「URIはリソースの名前だから名詞であるべき」というくだり。バージョン 2.0以前のRailsでは、

http://example.jp/sample/people/show/123

みたいなURIがデフォだったそう。しかしRails 2.0以降は

http://example.jp/sample/people/123

となって、動詞 show が省かれるようになった。HTTP通信で動詞を表すのはHTTPメソッドだから、URI自体が動詞を含むのはおかしいということらしい。ちなみにこのとき、名詞であるURIにアクセスするためのHTTPメソッドは GET ですね。

確かに自分が作っているサイトでもRailsで動かしてるものは、動詞を含まない名詞だけで表現されたURIを表示する。しかしながらCakePHPは

http://example.jp/sample/people/view/123

みたいなのがデフォだ。クールじゃない。というわけでURIから view を省くようにルーティングの処理を書き換え、各クラスのコントローラーも書き換えといた。

この『Webを支える技術』、プログラミングの話とかは載ってないから読んでいきなり何かの役に立つというタイプの本ではないけど、Web制作者なら職種にかかわらず読んどいた方が良さそうな本だなーと思いました。