Re:「autotestが止まらない。」 – 角谷HTML化計画 (2007-09-12)
$HOME/.autotest
require 'autotest/screen' Autotest::HOOKS.delete(:interrupt)
これで止まるようになりました。正しい対処かどうかはわかりませんが。
角谷さんにヒントをいただいたので深追いしてみました。
長くなるので、詳細は以下の通り。
まずは、メインのループ
ZenTest-3.6.1/lib/autotest.rb – Autotest#run()
167 loop do # ^c handler
168 begin
169 get_to_green
170 if @tainted then
171 rerun_all_tests
172 else
173 hook :all_good
174 end
175 wait_for_changes
176 rescue Interrupt
177 if @wants_to_quit then
178 break
179 else
180 reset
181 end
182 end
183 end
@wants_to_quitが立ったときに抜けられるみたい。
では、これを立てているところを探すと
ZenTest-3.6.1/lib/autotest.rb – Autotest#add_sigint_handler()
232 def add_sigint_handler
233 trap 'INT' do
234 if @interrupted then
235 @wants_to_quit = true
236 else
237 unless hook :interrupt then
238 puts "Interrupt a second time to quit"
239 @interrupted = true
240 sleep 1.5
241 end
242 raise Interrupt, nil # let the run loop catch it
243 end
244 end
245 end
ここ、おー:interruptを見てるな。さらに追う。
ZenTest-3.6.1/lib/autotest.rb – Autotest#hook()
420 def hook(name)
421 HOOKS[name].inject(false) do |handled,plugin|
422 plugin[self] || handled
423 end
424 end
ん、HOOKSが出てきた。そしてEnumerable#inject()の挙動がおもしろい。
そして、ここに:interruptを追加しているのは
ZenTest-3.6.1/lib/autotest/screen.rb – Autotest::Screen
57 Autotest.add_hook :interrupt do |at|
58 message 'Run Tests' if execute?
59 end
見つけた。おまえかっっ。
試しにこの3行をコメントアウトしたらちゃんと止まった。
つまり、この「ステータスメッセージを書き換えるだけ」のフックがある限り止まってくれない、ということになる。
そうすると以前は止まっていたのはなんで?てことになるわけですが・・・。
ひとまず、角谷さんの方法で手間も副作用も最小限でautotestがちゃんと止まるようになりました。
ありがとうございましたっっ!
しっかし、明示的に割り込みかけてるのに「Run Tests」って。
そもそも:interruptのフックはいらないんじゃないかなぁ。
コメント
なるほどっっっ!
http://rubyforge.org/tracker/index.php?func=detail&aid=13887&group_id=419&atid=1680
この件をつたない英語でポストしてみました。
書きって読みの数倍つらい・・・。