Reading Rake (2)
続き。
作られた時期のせいか、Rakeってばftoolsとか使ってるんだよなー。
getoptlongとか使ったことないし。
愚痴でした。
/lib/rake.rb(一部) -- Rake::Application#standard_exception_handling(抜粋)
# Provide standard execption handling for the given block. def standard_exception_handling begin yield rescue SystemExit, GetoptLong::InvalidOption => ex # Exit silently exit(1) rescue Exception => ex # Exit with error message ...... exit(1) end end
すぐyield。こうやって統一的に例外を扱うのか。へー。
Exceptionはすべての例外クラスのスーパークラスなので、例外は全部
捕まえられることになる。
SystemExit例外は組み込み関数exitした場合に上がるもの。
Rakefile中でexitされたりした場合のためかな。
あとオプションのエラーでも黙って終わると。けど実際に変なオプション
つけてやるとちゃんと怒るんだよなー。他のとこで言わせてるってことだろうか。
Rake::Application#standard_exception_handling -- Exit with error message以下
# Exit with error message $stderr.puts "rake aborted!" $stderr.puts ex.message if options.trace $stderr.puts ex.backtrace.join("\n") else $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" $stderr.puts "(See full trace by running task with --trace)" end exit(1)
前回での予想通り、--traceオプションの有無によってエラー時出力を変えている
のはこのメソッドだった。にしても、--traceついてないときの出力は
いちいち正規表現でバックトレースから拾ってたのか。
warnだと$VERBOSEに左右されるから$stderr.putsなんだろうな。
$stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
これがぱっと見少し判りにくいと思ったので書く。
puts (ex.backtrace.find{...} || "")
こうだ。
ところで一見ローカル変数にも見えるoptionsはメソッドだよなぁ。
/lib/rake.rb(一部) -- Rake::Application#options
# Application options from the command line def options @options ||= OpenStruct.new end
だそうです。
OpenStructクラスは標準添付ライブラリostructをrequireして使えるものだが、
正直存在を知りませんでした。リファレンスによると、
Python 風の「attr on write」Struct
だそうです。
left_var ||= right_value
は、
left_var = (left_var || right_value)
/lib/rake.rb(一部) -- Rake::Application#run, init, load_rakefile, top_level
前回見たrunも乗せる。見るのはrunのstandard_exception_handling内で
呼ばれていた3つのメソッド。
def run standard_exception_handling do init load_rakefile top_level end end # Initialize the command line parameters and app name. def init(app_name='rake') standard_exception_handling do @name = app_name handle_options collect_tasks end end # Find the rakefile and then load it and any pending imports. def load_rakefile standard_exception_handling do raw_load_rakefile end end # Run the top level tasks of a Rake application. def top_level standard_exception_handling do if options.show_tasks display_tasks_and_comments elsif options.show_prereqs display_prerequisites else top_level_tasks.each { |task_name| self[task_name].invoke } end end end
なんというか、キレイにメソッド分けされててコールグラフの出力みたいだ。
この中を次で読む。