鳩舎

レースしない

RubyKaigi 1 日目

ルビー会議楽しいですね。

ということで RubyKaigi はおいておいて、メソッドキャッシュの話をしましょう。笹田さんの発表の最後で出てきたやつです。僕は一人で感動に打ち震えていましたが、 IRC に書いたのは『Charlis++』とか書いててですね、ちげーよ Charlie だよみたいなことを家に帰ってから気づいて、アーオって気持ちになりました。

そんなこんなで問題のチケットはこちら。もうチケット名みただけでヨダレ垂らしながら転げまわりたくなりますね。やったぜクラスヒエラルキーメソッドキャッシュサイコー。

ちょっと関係ないコミットとかも混ざって出てるんですけど Github でどういう変更がなされたかが見れます。さらっと流し読みしながらどう変わったかを見てみましょう。

bye bye ruby_vm_global_state_version

メソッドキャッシュに使われていた ruby_vm_global_state_version が削除されています(vm_insnhelper.h#261)。

いままでは ruby_vm_global_state_version で一括管理されていたものが分割された模様。ruby_vm_sequence, ruby_global_method_state_version, ruby_global_const_state_version とあとはクラス / モジュールオブジェクトに生えてる seq で管理されてるのかな?あと、 ruby_vm_global_state_versionVALUE だったんですけど、 ruby_vm_sequence とかは vm_state_version_t という型になっています。中身は unsigned long longuint64_t っぽい(internal.h#58)。

hello method_cache_entry

前は cache_entry っていう構造体があって(vm_method.c#25)、それがメソッドキャッシュのデータだったんだけど、廃止されて method_cache_entry に置き換わってます(internal.h#74)。合わせて iseq_inline_cache_entry のメンバも変わってますね(vm_core.h#135)。

肝心のメソッドキャッシュそのものはどうなってんのかと思ったらクラスが自分のシーケンス持つように変わってるみたいですね(vm_method.c#512)。

んで、実際にクラスが更新されたら rb_clear_method_cache_by_class なりが叩かれて、rb_class_increment_sequence に飛んでクラスのシーケンスが変わると(vm_method.c#27)。

ただこれ、 seq をインクリメントし続けるのが不安な感じするけど大丈夫なのかな。オーバーフローしそうな気がするけど、大丈夫なのかな……

以上、メモでした。

これが Ruby 2.1.0 に入ると僕の uninclude gem は動かなくなりますね……どうしようかな……追従するべきだろうな……でも subclasses とかが追加されてるから大変そうだ……

目黒.rb meetup #1

http://megurorb.github.io/blog/2013/05/10/meetup-16-may-2013/

形式としては

  1. お題のプロジェクト(https://github.com/megurorb/sit-up)を clone してくる
  2. リファクタリング祭り(1時間)
  3. PR にして投げて、みんなでレビュー(レビュイーは意図の説明をする)

という会でした。2 の段階では青い画面の投影されたスクリーンを向いて全員が黙々とコードを書き続けるという狂気に満ちた絵面になっており、たまたま見かけた人が戦慄するという、謎のイベントでした。

みんな気になる所が違う

例えば僕なんかは、とりあえず落としてきたら rspec 実行して、コケてるテスト見つけたからとりあえず Green にして、そしたら次はメソッド名が気に食わないことこの上ないから名前を直して……みたいな感じだったんですけど、人によっては『まずは Rakefile でテスト実行できるように!』とか『Spork いれてテストサイクル早くしてからが本番や!』みたいな感じで、着手箇所が違うのも面白かったです。

あとはもう話が飛び飛びで、カバレッジの話をしたり、レビューツールの話をしたり、最近の SVN はすごいみたいな話を聞いて感動したりしてました。

Array#flattten に引数与えられるのとか知らんかった……

ということで

目黒.rb meetup #2 期待してます。

プログラミングの話

この辺見て、いつも思ってること。

プログラミングは手段です。僕にとっては。

「動けばいいコード」は糞コードだ

でしょうね。としか言い様がないです。

あえて例え話にして、プログラミングを車の運転だとします。プログラマは運転手です。

でまぁ、アプリを作るってのが伊豆の旅館に行くことだとしましょう。この時、僕の運転する目的は伊豆に行くことです。間違っても運転することは目的じゃないです。なので別に運転に特に気を使うことはありません。

そこに突然 F1 ドライバーがやってきて、『お前のカーブの曲がり方は下手くそだ』とか『もっといいルート選択がある』とか『こんな運転の仕方じゃガソリン代がもったいない。すぐに路銀がつきてしまう。もっと急加速を減らすべきだ』とかご高説を頂いてもですね、はぁ、としか言い様がないです。そりゃ、あなたは運転が好きで F1 ドライバーで、運転すること自体が目的で、運転技術に誇りを持っているんだろうけれども、別に僕は伊豆に着きゃなんでもいいんですよ。一応言っておくと、別にわざわざ悪い方法を取ろうと思ってませんよ。

ドリフトの上手いかけ方とか知らないし、別に覚える気もないですからね。いきなり頭ごなしに糞とか言われても困ります。心象悪いです。下手すりゃ乗ってる車ごと否定されますからね。『えっ、お前 PHP 乗ってんの!?馬鹿だろ!』とか。うわーんもうやめてよー。

プログラミングするのは楽しいです

とはいえ、僕だって運転するのは好きですよ。だって、良いカーブの曲がり方を覚えればそれだけ早く伊豆につけるし、いい車を選べばそれだけ運転だって楽になる。アメ車の Haskell や四駆の Scala だって乗ってみたら楽しいだろうし、いろいろ手を出してみたくなります。新しいホイールが出たら欲しいし。

そういう時 F1 ドライバーの人にアドバイスをもらったり、お叱りを受けたりするのはすげーありがたいなと思うし、感謝しきりです。

一人でドライブをする時は、完全に運転することが目的です。楽しいじゃないですか、運転するの。だってアクセル踏んだらどこまでもいけるんですよ。ちょっとした全能感とか開放感ありますよね。

でまぁそうやって運転も悪く無いかな?って思えるようになったら、伊豆に行くときもいろいろ言ってもらえるのが嫌なことから嬉しいことになりました。これは単に僕が変わっただけですが。

F1 ドライバーの方へ

皆さんからすれば、運転が手段な僕らの運転技術は見るに耐えず、嘲笑の的かと存じます。

でも突然やってきて運転技術をボロクソに言われても、正直身にしみないです。ただの鬱陶しい人だと思います。でも皆さんの持っている知識やテクニックは、それを覚えた『伊豆に行きたいだけの運転手』の人たちをもっと幸せにできます。

でですね、出来れば F1 ドライバーの皆さんにも、伊豆の楽しさを知っていただきたいのですよ。たまには運転を手段にしたって良いではないですか。行楽旅行の運転に使ったら、俺の技術が汚れる、とお思いかもしれませんが、たまには旅行を楽しんだっていいんじゃないでしょうか。

大元に戻って、プログラミングを学ぶときの話

人には向き不向きがあります。プログラミングを覚えなくたって生きていけます。プログラミングは本当に自分の人生の投資先として価値があるか考えましょう。

あとはわからん。思いつかん。何言われたって人間やるときゃやるしやらないときはやらないでしょ。モチベーションを維持できる何か(そのものが好き、それによって作るものが好き)があればまぁ大抵なんとかなるんじゃないでしょうか。

まとめ

各位、なかよく。

適切な名前がつかないモデル

ちょっと目についたので。Dis りたい訳じゃないです。

これ適切な名前が見つからないとき困るんだよなぁ。あとで思いついて変更なんて作業はしたくないし。割り切ってRoomUser式に統一した方が気が楽だと思う。

http://b.hatena.ne.jp/kensatou/20130512#bookmark-145186810

id:kensatou さんの言う『適切な名前が見つからない時』がわからないのでなんとも言いがたいのですが、割りきって RoomUser 式に統一は悪手だと僕は思っています。

大体からして何らかの案件なり要望なり青写真なりをモデルに落とし込んでいる時に『名前がつかないモデル』が出てくるということは、それは何かが噛み合っていない状況のアラートだと思っています。

ぱっと思いつく状況だと

  1. 英語力が足りない: 僕は大抵このパターンなので辞書を引きます。それでもわかんなかったら英語が堪能な同僚に相談です。
  2. そのモデルがなぜ必要なのかを上手に説明できない: 関連モデルなのは知っているけれどそれがなんの関連なのかはわかっていない。仕様書を読んだり、ディレクターと話すといいと思います。
  3. 過去のコードである: 書き直しましょう。

とかかなぁ。他にも起こりうる状況があったら教えてほしいです。適当な名前をつけるならまだしも、適当な名前しか付けられない状況、そのドメインに対する知識や理解が薄いので、バグを埋め込む危険があると思います。

それでも思いつかないなら日本語での呼称をそのまま直訳で英語にするといいと思います。RelationOfRoomWithUser とか。 RoomUser と情報量変わらないですけど、 RoomUser を見た時の『部屋のユーザーっていうモデルなのかな?』という誤解は避けられそうです。

関連モデルの命名

今日は Rails での『関連モデル』の名前について考える。

構造としてはこんな感じ。

・ルーム(Room)に所属するユーザー(User)
・ルーム(Room)での管理者権限を持つユーザー(User)

どちらの関連も N:N の関連。いわゆる has_may な感じ。

で、こういう時の命名って Room モデルと User モデルだから RoomUser とか UserRoom とかっていうモデルやテーブルを作りがちなのだけれど、今回は同様の形態の関連が2つあるのでちょっと微妙な事になりそう。

っていうか、まずもって RoomUser モデルってなんだよ。なんのモデルだよそれ。って感じなので名前を考える。

ルーム(Room)に所属するユーザー(User)

関連モデルのデータは大抵2つのフィールドを持っている。 Migration あたりから抜き出すと

t.references :room
t.references :user

みたいな具合。つまるところ room_iduser_id を持っているわけだけれども、この2つを持ちそうなモデルってのは何なんだろう。これだけでは情報が少なさすぎるので、この関連テーブルを使っての集合に Room モデルからどうアクセスするのかを考える。

class Room < AR::Base
  has_many {関連モデル}
  has_many :members,
    through: {関連モデル},
    source: :user
end

あー、部屋のメンバーとしての関連なのかーとわかってきた。そうなったらもう話は簡単で、メンバーであること、というそのものの命名にしよう。 Room::Membership なんてどうだろうか。

class Room::Membership < AR::Base
  belongs_to :room
  belongs_to :user
end

class Room < AR::Base
  has_many :memberships
  has_many :members,
    through: :memberships,
    source: :user
end

『部屋のメンバーであること』のモデルになった。membership.destroy であるユーザーがあるルームのメンバーでなくなるのは、なかなかわかりやすい。

ルーム(Room)での管理者権限を持つユーザー(User)

テーブルの構造は N:N の関連モデルなので Membership と変わらない。どうアクセスされるか見よう。

class Room < AR::Base
  has_many {関連モデル}
  has_many :administrators,
    through: {関連モデル},
    source: :user
end

あー、管理者の関連モデルなのか。なるほどー、という気分になった。先ほどは『メンバーであること』のモデルを作ったけど、じゃあ今回は『権限そのもの』のモデルを作ったほうがすんなり行くかもしれない。

僕は英語が苦手なので、辞書をひっぱり回すと例えば Room::AdministrativePrivilege とかいいんじゃない?という感じになる。

class Room::AdministrativePrivileage < AR::Base
  belongs_to :room
  belongs_to :user
end

class Room < AR::Base
  has_many :administrative_privileges
  has_many :administrators,
    through: :administrative_privileges,
    source: :user
end

名前ながいな!って思うけど、今後新しくジョインするメンバーはソースコードを読んで、その関連モデルが一体なんのための関連モデルか悩まずに済むんじゃなかろうか。

よりよい命名があったら教えてほしい。