method_source is 何?
minimum sample
require 'method_source'
def my_important_method
# do nothing, just sleep
sleep 4
'successfuly done with my hard work!!'
end
method = method(:my_important_method)
method.source.display
すると。。。
def my_important_method
# do nothing, just sleep
sleep 4
'successfuly done with my hard work!!'
end
メソッドの定義がプリントされる。
どんな実装か
Method objectからは定義もとのfile, lineが取れる。
そのファイルを全部読み込み、line以下を全て取ってくる
lines = File.readlines(file)
lines = lines[(line - 1)..-1]
linesをイテレートして、methodの定義が終わるところを判定する。
lines.each do |v|
code << v
return code if complete_expression?(block ? block.call(code) : code)
end
これでmethod定義が抜き出せたので、あとは表示するだけ
知恵
rescueされるerrorを判別するだけのmodule
def hoge
rescue MyModule
end
module MyModule
def self.===(error)
some_condition(error)
end
end
evalを使ってstrの構文をチェックだけして、BEGIN throwで実行させずに戻る
catch(:valid) do
eval("BEGIN{throw :valid}\n#{str}")
end
どうゆう仕組みか?
strが構文としておかしいとSyntaxErrorが出て throwされない。
strが構文としてokだったらそのstr実行前に BEGIN で登録された throwが走る。
所感
まず BEGIN
とか知らなかった。
この3行でこれだけのこと詰め込めるrubyはスマートで好き。