guard-spork と guard-ego を組み合わせる場合の問題点
該当 Guard クラス(guard-spork なら Guard::Spork、guard-ego なら Guard::Ego)の検索に問題がある様です。
- guard 0.3.10
- guard-spork 0.1.4
- guard-ego 0.0.1
guard-ego を利用する事で、Guardfile を変更した際に Guard が再起動される様になります。
その際に、guard-spork も利用していた場合、以下の様なエラーメッセージが出力されて例外終了します。
Guard is now restarting... ERROR: Invalid Guardfile, original error is: wrong number of arguments (2 for 1) ERROR: Guard::Ego guard failed to achieve its <run_on_change> command: exit Guard Guard::Ego has just been fired
これは、Guard.get_guard_class の処理に問題があるためと思われます。
def get_guard_class(name) require "guard/#{name.downcase}" klasses = [] ObjectSpace.each_object(Class) do |klass| klasses << klass if klass.to_s.downcase.match(/^guard::#{name.downcase}/) end klasses.first rescue LoadError UI.error "Could not find gem 'guard-#{name}', please add it in your Gemfile." end
何が問題かというと、guard-spork は Guard::Spork と Guard::Spork::Runner というクラスをロードします。そのため、上記のコードでは、Guard::Spork::Runner が使われてしまう可能性があるわけです(Guard::Spork::Runner が使われた場合、引数の数が異なるために例外となります)。
guard を作る際の規約は、ドキュメントの"Create a guard"の節で説明されています。以下は一部を抜粋したものです。
- guard の名称は、
- ファイル名 guard-
.rb - クラス名は Guard::
- ファイル名 guard-
- guard のクラスは Guard::Guard クラスを継承し、特定のメソッドをオーバーライドする
これを見た感じ、ObjectSpace からクラス名の前方一致でクラスを拾い集める必要性はなく、特定のクラス名が使えるか否かで判断できるように思えます。
もしかしたら、使い方を間違えているだけかもしれませんが、恥ずかしげもなく英語でバグレポートを出してみました。
github でバグ報告をする場合、課題報告が先なのか、プルリクエストでやれるのか、よくわかりません。なので、とりあえず gist と課題報告で済ませてしまいました。
追記: 2011/02/21
pull request してマージされました。