的那一刻說我有:我可以訪問結合在一個異常的紅寶石
begin
2.times do
a = 1
1/0
end
rescue
puts $!
debugger
end
在這個例子中,我想要得到的a
值。如果a
在begin
塊中初始化,那麼我可以在救援時訪問它。但是,在本例中,a
是塊本地的。有沒有辦法在發生異常時獲得綁定?
的那一刻說我有:我可以訪問結合在一個異常的紅寶石
begin
2.times do
a = 1
1/0
end
rescue
puts $!
debugger
end
在這個例子中,我想要得到的a
值。如果a
在begin
塊中初始化,那麼我可以在救援時訪問它。但是,在本例中,a
是塊本地的。有沒有辦法在發生異常時獲得綁定?
似乎有一個黑客可能做到這一點。這是不是很漂亮,但:
class Foo < Exception
attr_reader :call_binding
def initialize
# Find the calling location
expected_file, expected_line = caller(1).first.split(':')[0,2]
expected_line = expected_line.to_i
return_count = 5 # If we see more than 5 returns, stop tracing
# Start tracing until we see our caller.
set_trace_func(proc do |event, file, line, id, binding, kls|
if file == expected_file && line == expected_line
# Found it: Save the binding and stop tracing
@call_binding = binding
set_trace_func(nil)
end
if event == :return
# Seen too many returns, give up. :-(
set_trace_func(nil) if (return_count -= 1) <= 0
end
end)
end
end
class Hello
def a
x = 10
y = 20
raise Foo
end
end
class World
def b
Hello.new.a
end
end
begin World.new.b
rescue Foo => e
b = e.call_binding
puts eval("local_variables.collect {|l| [l, eval(l)]}", b).inspect
end
來源:How can I get source and variable values in ruby tracebacks?
我不知道跨紅寶石雖然我記得RBX有一些巧妙的'Backtrace'對象可幫助你有效的解決方案的。你能否擴展你想要實現的目標? – riffraff
@riffraff不知道如果我能更好地解釋它。我需要檢索一個(在這個例子中)的值。對於真實世界的場景,想象2X塊是一個迭代塊,每次從CSV文件中檢索一行。在某些情況下,(CSV文件的)行號203445發生異常。現在,我可以去那一行了。在CSV文件中檢查該特定行是否「OK」。或者我可以拯救並開始一個調試器會話。在此刻。我需要能夠看到綁定,在例外 – Vassilis
謝謝,我所問的原因是,在類似的情況下,我有在do塊內的錯誤管理代碼,所以我有機會修復單個值並繼續前進,這似乎適合你的情況,儘管它沒有回答原來的問題,恐怕。我可以建議的唯一的事情是,如果錯誤不在本機代碼中,你可以重寫提升/失敗來存儲調用者的綁定,但它只是一個解決方案 – riffraff