Ruby 2.0 リリース週記 (2012/05/21 - 27)

今週も、今週入ったばかりの新機能を紹介します。ちょっと地味というか、細かい話ですが。

今週のニュース: caller の改善で文字列のパースが不要に

背景

かつてより、コールスタックを配列として取り出す機能 Kernel#caller があります。

def foo
  caller(0).each {|x| p x }
end

def bar
  foo
end

def baz
  bar
end

baz
$ ./ruby test.rb
"test.rb:2:in `foo'"
"test.rb:6:in `bar'"
"test.rb:10:in `baz'"
"test.rb:13:in `<main>'"

こんな感じ。ここからファイル名だけを取りたいと思ったら、文字列の先頭からコロンまでを切り出す処理が必要です (そういう処理をパースといいます) 。Ruby ではパースは正規表現で簡単にできるものの、盲点が発生しやすいので、あまり好ましいコードではありません。*1
ということで、「パース不要にしてくれ」という声は昔からちょくちょくありました。[ruby-core:13842] [ruby-dev:42345] [ruby-core:24805]

今回導入された機能

そこで我らがささださんが、caller の代わりに使える RubyVM::FrameInfo.caller というメソッドを試験的に導入しました ([ruby-core:45253]) 。文字列の代わりに、RubyVM::FrameInfo クラスのオブジェクトが得られます。このクラスにはファイル名を返す #filename というメソッドがあるので、パースが必要ありません。

def foo
  RubyVM::FrameInfo.caller(0).each {|x| p [x, x.filename] }
end
(略)
$ ./ruby test.rb
[test.rb:2:in `foo', "test.rb"]
[test.rb:6:in `bar', "test.rb"]
[test.rb:10:in `baz', "test.rb"]
[test.rb:13:in `<main>', "test.rb"]

他にも、行番号を取り出す #line_no やメソッド名相当を取り出す #name などもあります。

考察

長々と書きましたが、一般ユーザが直接使うことはあまりない機能だと思います。というより、個人的には推奨しません。怪しいコードを簡単に書けそうなので。
想定されているユーザは Web などのフレームワーク開発者 *2 などでしょうか。なので、実際のユーザにこの機能の恩恵が届くのは、2.0 リリースより先になるのではないかと思います。プログラミング言語の開発は将来に向けた種まきであることが結構あります。
それ以外には、デバッガやプロファイラの開発に向けた布石と考えられるかもしれません。これからのささださんの活躍にご期待ください。


ちなみに、RubyVM::FrameInfo.caller という名前は長くわかりにくいということで、代替 API の案が募集されています ([ruby-core:45253]) 。また、機能自体に関するコメントも求められていますので、興味のある方は議論に参加されてみるといいと思います。

おまけ: 今のチケット残数

通称コミグズランキング *3 。目立った変化はありません。

 1: matz (137 tickets)
 2: nobu (66 tickets)
 3: ko1 (56 tickets)
 4: akr (31 tickets)
 5: mrkn (22 tickets)
 6: MartinBosslet, nahi (18 tickets)
 8: keiju (15 tickets)
 9: kosaki, naruse, usa (13 tickets)
12: authorNari (11 tickets)
13: drbrain, marcandre (10 tickets)
15: knu, tenderlovemaking (9 tickets)
17: seki, sorah (7 tickets)
19: kouji, mame (6 tickets)
21: suke (4 tickets)
22: JEG2, akira, duerst, nagai, shyouhei, takano32, tarui, yugui (3 tickets)
30: shugo (2 tickets)
31: Glass_saga, aamine, kou, metanest, nagachika, ngoto (1 ticket)

*1:例えば、ファイル名にコロンが入ってる可能性。eval の第 3 引数でファイル名を任意に偽装できることも忘れがちです。

*2:Rails アプリで開発モードだと、例外発生時にスタックトレースが表示されると思いますが、あの手の機能が作りやすくなります。

*3:もちろん本気で言ってるわけではありません。むしろ、このランキングは、Ruby 開発において「頼りにされている度合い」を表しているものと思われます。参考発言