2017-08-13 11 views
4

現在実行中のRubyスクリプトを中断し、更新してから実行を継続できますか?Ruby - 更新実行スクリプト

など。スクリプトを持っていたと言う:

(0..10).each do |x| 
    puts x 
end 

は、あなたがそれを中断することができ、第二行が読み込まように変更します。

puts x * 2 

その後、実行を継続?

+0

あなたは.rbs' 'リロードするload''に見たことがありますか? –

答えて

0

pryは種類のこのような何かをし(私たちは、割り込み時間が短すぎるような些細な引数を無視すると仮定した場合)

私はそうのようなスクリプトtest.rbお持ちの場合:

require 'pry' 

result = [] 
5.times do |i| 
    result << "#{i}" 
    binding.pry if i == 2 
end 

puts "result is ", result.join(",") 

が続いて第3回繰り返しで、それは私がコマンドを入力することができますブレークポイントで一時停止しますが。私は

edit test.rb 

を入力した場合、その後$EDITOR(またはナノ)を開きますと、私は、ソースコードを変更することができます。テキストエディタを終了すると、pryは同じブレークポイントになりますが、変更されたコードを使用して既存のコードを再実行します。これは一種のサブシェルです。元のコードを元のブレークポイントに戻すと元のコードに戻ります。この2番目のブレークポイントを終了すると、私はbashに戻り、ファイルに対する私の編集内容は保持されました。

editにパスを渡す代わりに、メソッド名を渡すこともできますが、同じ効果(サブシェル)があります。私は

result << "#{i}*" 

result << "#{i}" 

を変更するのであれば、いずれの場合には、上記のコードで、私はresult is 0,1,2,3,4またはresult is 0*,1*,2*,3*,4*ではなくresult is 0,1,2,3*,4*のいずれかを見ることになります。

また、ブレークポイントでローカル変数を簡単に編集することもできます。例えば:

require 'pry' 

a = 1 
binding.pry 
puts a 

私はブレークポイントを終了しa = 2を入力し、control+d場合、プログラムが期待されるような2を印刷します。また、実行時メタプログラミングを使用して、メソッド、インスタンス変数などをオーバーライドすることもできます。

2

あなたが実際にプロセスを停止する場合は、あなたは、割り込み信号をtrapファイルに現在の進行状況を書いて、[バックアップの開始時に、そのファイルを探すことができます:

progress_file = './script_progress.txt' 
x = if File.exists?(progress_file) 
    File.read(progress_file).to_i 
else 
    0 
end 

Signal.trap("INT") { 
    File.open(progress_file, 'w') { |f| f.write(x.to_s) } 
    exit 
} 

while x <= 10 do 
    puts x 
    x += 1 

    sleep(1) 
end 

結果:

(それだけで正常に終了した場合でも)
$ rm script_progress.txt 
$ ruby example.rb 
0 
1 
2 
3 
^C$ cat script_progress.txt 
4 
# modify example.rb here, changing `puts x` to `puts x * 2` 
$ ruby example.rb 
8 
10 
12 
14 
16 
18 
20 

また、ファイルにスクリプトが終了する任意の時間を書くことat_exitを使用することができます。

progress_file = './script_progress.txt' 
x = if File.exists?(progress_file) 
    File.read(progress_file).to_i 
else 
    0 
end 

at_exit do 
    File.open(progress_file, 'w') { |f| f.write(x.to_s) } 
end 

while x <= 10 do 
    puts x 
    x += 1 

    sleep(1) 
end 

結果:あなたはプロセスが実行されているが、ちょうど機能的に異なるを切り替えることができるように保持したい場合は

$ ruby example.rb 
0 
1 
2 
3 
4 
^Cexample.rb:16:in `sleep': Interrupt 
    from example.rb:16:in `<main>' 

# modify example.rb to double the output again 
$ ruby example.rb 
10 
12 
14 
16 
18 
20 

、あなたがProcess.killを使用してカスタム信号を送ることができます。

pid = fork do 
    Signal.trap("USR1") { 
    $double = !$double 
    } 

    (0..10).each do |x| 
    puts $double ? x * 2 : x 

    sleep(1) 
    end 
end 

Process.detach(pid) 
sleep(5) 
Process.kill("USR1", pid) 
sleep(6) 

の検索結果を:

$ ruby example.rb 
0 
1 
2 
3 
4 
10 
12 
14 
16 
18 
20 

これを使用して、rubyにloadというファイルを送信することができます再び:

File.open('print_number.rb', 'w') do |file| 
    file.write <<-contents 
def print_number(x) 
    puts x 
end 
contents 
end 

pid = fork do 
    load './print_number.rb' 
    Signal.trap("USR1") { 
    load './print_number.rb' 
    } 

    (0..10).each do |x| 
    print_number(x) 

    sleep(1) 
    end 
end 

Process.detach(pid) 
sleep(5) 
File.open('print_number.rb', 'w') do |file| 
    file.write <<-contents 
def print_number(x) 
    puts x * 2 
end 
contents 
end 
Process.kill("USR1", pid) 
sleep(6) 

結果:

$ ruby example.rb 
0 
1 
2 
3 
4 
10 
12 
14 
16 
18 
20 
+0

クレイジーハックがあります! Rubyはすばらしいです:) –

+1

私はまた、[このプレゼンテーション](http://avdi.org/talks/rockymtnruby-2011/things-you-didnt-know-about-exceptions.html)を見て、同じようにクレイジーなアイデアを示しました'raise'メソッドをオーバーライドするなどのフロー制御を中心に、途中で実行を続行します。 –

関連する問題