ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

昨日見たRubyの「なんじゃこりゃあ」な書き方


普段なら

[[1,2], [5,3], [4, 1]].sort_by{|x| x.first }

と書くところのやつですが、何この記法…

何はなくともまずはドキュメント

というわけでドキュメントを確認していきましょう。メソッド呼び出しには違いないはずなので、とりあえずまずはメソッド呼び出しを確認します。

ブロックつきメソッドの呼び出し方

ブロックつきのメソッドを呼び出す方法は次の3パターンです。

method(arg1, arg2, ...)  do [`|' 式 ... `|'] 式 ... end
method(arg1, arg2, ...) `{' [`|' 式 ... `|'] 式 ... `}'
method(arg1, arg2, ..., `&' proc_object)

上のツイートの例は3つ目のものが近そうです。となると上のhash_object:firstということになりますが…?

Procへのの暗黙的な変換

ここでSymbolからProcへの暗黙的な変換が行われているようです。SymbolクラスではインスタンスをProcへ変換するときに呼び出されるto_procが以下のように再定義されています。

to_proc -> Proc[permalink]
self に対応する Proc オブジェクトを返します。

生成される Proc オブジェクトを呼びだす(Proc#call)と、 その第一引数の self という名前のメソッドを 残りの引数を渡して呼びだされます。

:to_i.to_proc["ff", 16]  # => 255
(1..3).collect(&:to_s)  #=> ["1", "2", "3"]
(1..3).inject(&:+)      #=> 6

class Symbol

2番めの例がまさにそれですね。

というわけで…

  • ブロックをとるメソッドでは、&のあとの値は暗黙的にProcへと変換される
  • ブロックに渡される引数はそのままの順番で、変換されたProcオブジェクトのProc#callに渡される

ということが判りました。