Rails named scope デフォルト引数
Rails の named scope にデフォルト引数を与えると便利。
class Book < AR::Base scope :published, ->(at = Time.now) { where('published_at > ?', at) } end
こうしてデフォルト引数を与えておくと
Book.published # => 現在公開済みの本 Book.published 1.day.ago # => 1日前から公開済みの本
みたいに出来る。
>> Operator がわからない
my @scores = 'Ana' => 3 say 1 + [max] @scores>>.key>>.chars # => 4
なにこれどういうこと……?
追記
map
だ。
my @values = 'Ana', 'David' @values>>.chars # => 3 5
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_version
は VALUE
だったんですけど、 ruby_vm_sequence
とかは vm_state_version_t
という型になっています。中身は unsigned long long
か uint64_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/
形式としては
- お題のプロジェクト(https://github.com/megurorb/sit-up)を clone してくる
- リファクタリング祭り(1時間)
- PR にして投げて、みんなでレビュー(レビュイーは意図の説明をする)
という会でした。2 の段階では青い画面の投影されたスクリーンを向いて全員が黙々とコードを書き続けるという狂気に満ちた絵面になっており、たまたま見かけた人が戦慄するという、謎のイベントでした。
みんな気になる所が違う
例えば僕なんかは、とりあえず落としてきたら rspec 実行して、コケてるテスト見つけたからとりあえず Green にして、そしたら次はメソッド名が気に食わないことこの上ないから名前を直して……みたいな感じだったんですけど、人によっては『まずは Rakefile でテスト実行できるように!』とか『Spork いれてテストサイクル早くしてからが本番や!』みたいな感じで、着手箇所が違うのも面白かったです。
あとはもう話が飛び飛びで、カバレッジの話をしたり、レビューツールの話をしたり、最近の SVN はすごいみたいな話を聞いて感動したりしてました。
Array#flattten に引数与えられるのとか知らんかった……
ということで
目黒.rb meetup #2 期待してます。
プログラミングの話
この辺見て、いつも思ってること。
- プログラミングはアプリを作ることの手段なのか - 銀の人のメモ帳
- プログラミングはそれ自体が目的であっていい - mizchi log
- プログラミングを勉強したい人が勉強する前にすべきこと - もとまか日記
プログラミングは手段です。僕にとっては。
「動けばいいコード」は糞コードだ
でしょうね。としか言い様がないです。
あえて例え話にして、プログラミングを車の運転だとします。プログラマは運転手です。
でまぁ、アプリを作るってのが伊豆の旅館に行くことだとしましょう。この時、僕の運転する目的は伊豆に行くことです。間違っても運転することは目的じゃないです。なので別に運転に特に気を使うことはありません。
そこに突然 F1 ドライバーがやってきて、『お前のカーブの曲がり方は下手くそだ』とか『もっといいルート選択がある』とか『こんな運転の仕方じゃガソリン代がもったいない。すぐに路銀がつきてしまう。もっと急加速を減らすべきだ』とかご高説を頂いてもですね、はぁ、としか言い様がないです。そりゃ、あなたは運転が好きで F1 ドライバーで、運転すること自体が目的で、運転技術に誇りを持っているんだろうけれども、別に僕は伊豆に着きゃなんでもいいんですよ。一応言っておくと、別にわざわざ悪い方法を取ろうと思ってませんよ。
ドリフトの上手いかけ方とか知らないし、別に覚える気もないですからね。いきなり頭ごなしに糞とか言われても困ります。心象悪いです。下手すりゃ乗ってる車ごと否定されますからね。『えっ、お前 PHP 乗ってんの!?馬鹿だろ!』とか。うわーんもうやめてよー。
プログラミングするのは楽しいです
とはいえ、僕だって運転するのは好きですよ。だって、良いカーブの曲がり方を覚えればそれだけ早く伊豆につけるし、いい車を選べばそれだけ運転だって楽になる。アメ車の Haskell や四駆の Scala だって乗ってみたら楽しいだろうし、いろいろ手を出してみたくなります。新しいホイールが出たら欲しいし。
そういう時 F1 ドライバーの人にアドバイスをもらったり、お叱りを受けたりするのはすげーありがたいなと思うし、感謝しきりです。
一人でドライブをする時は、完全に運転することが目的です。楽しいじゃないですか、運転するの。だってアクセル踏んだらどこまでもいけるんですよ。ちょっとした全能感とか開放感ありますよね。
でまぁそうやって運転も悪く無いかな?って思えるようになったら、伊豆に行くときもいろいろ言ってもらえるのが嫌なことから嬉しいことになりました。これは単に僕が変わっただけですが。
F1 ドライバーの方へ
皆さんからすれば、運転が手段な僕らの運転技術は見るに耐えず、嘲笑の的かと存じます。
でも突然やってきて運転技術をボロクソに言われても、正直身にしみないです。ただの鬱陶しい人だと思います。でも皆さんの持っている知識やテクニックは、それを覚えた『伊豆に行きたいだけの運転手』の人たちをもっと幸せにできます。
でですね、出来れば F1 ドライバーの皆さんにも、伊豆の楽しさを知っていただきたいのですよ。たまには運転を手段にしたって良いではないですか。行楽旅行の運転に使ったら、俺の技術が汚れる、とお思いかもしれませんが、たまには旅行を楽しんだっていいんじゃないでしょうか。
大元に戻って、プログラミングを学ぶときの話
人には向き不向きがあります。プログラミングを覚えなくたって生きていけます。プログラミングは本当に自分の人生の投資先として価値があるか考えましょう。
あとはわからん。思いつかん。何言われたって人間やるときゃやるしやらないときはやらないでしょ。モチベーションを維持できる何か(そのものが好き、それによって作るものが好き)があればまぁ大抵なんとかなるんじゃないでしょうか。
まとめ
各位、なかよく。
適切な名前がつかないモデル
ちょっと目についたので。Dis りたい訳じゃないです。
これ適切な名前が見つからないとき困るんだよなぁ。あとで思いついて変更なんて作業はしたくないし。割り切ってRoomUser式に統一した方が気が楽だと思う。
id:kensatou さんの言う『適切な名前が見つからない時』がわからないのでなんとも言いがたいのですが、割りきって RoomUser 式に統一は悪手だと僕は思っています。
大体からして何らかの案件なり要望なり青写真なりをモデルに落とし込んでいる時に『名前がつかないモデル』が出てくるということは、それは何かが噛み合っていない状況のアラートだと思っています。
ぱっと思いつく状況だと
- 英語力が足りない: 僕は大抵このパターンなので辞書を引きます。それでもわかんなかったら英語が堪能な同僚に相談です。
- そのモデルがなぜ必要なのかを上手に説明できない: 関連モデルなのは知っているけれどそれがなんの関連なのかはわかっていない。仕様書を読んだり、ディレクターと話すといいと思います。
- 過去のコードである: 書き直しましょう。
とかかなぁ。他にも起こりうる状況があったら教えてほしいです。適当な名前をつけるならまだしも、適当な名前しか付けられない状況、そのドメインに対する知識や理解が薄いので、バグを埋め込む危険があると思います。
それでも思いつかないなら日本語での呼称をそのまま直訳で英語にするといいと思います。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_id
と user_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
名前ながいな!って思うけど、今後新しくジョインするメンバーはソースコードを読んで、その関連モデルが一体なんのための関連モデルか悩まずに済むんじゃなかろうか。
よりよい命名があったら教えてほしい。