经过艰苦的讨论,得出一个不完美的解决方案
[pre lang="ruby" line="1"]def wrap_trace_capture(script)
"
begin
#{script}
rescue Exception=>e
true_backtrace = Marshal.load(Marshal.dump(e.backtrace))
e.define_singleton_method(:correct_backtrace) do
e.backtrace.replace(true_backtrace)
end
raise e
end
"
end
begin
eval(wrap_trace_capture('foo'))
rescue Exception=>e
p e
p e.backtrace
e.correct_backtrace if e.respond_to?(:correct_backtrace)
raise e
end
[/pre]
有任何改进/建议么?
module EvalStackFix
module_function
#--------------------------------------------------------------------------
# ● 包装eval内容,截取正确的backtrace
#--------------------------------------------------------------------------
def wrap(script)
"begin
#{script}
# 上面一行没有缩进是因为script可能包含=begin关键字,而=begin前面不能有空格
rescue Exception=>e
true_backtrace = Marshal.load(Marshal.dump(e.backtrace)) # deep clone
e.define_singleton_method(:correct_backtrace) do
e.backtrace.replace(true_backtrace)
end
raise e
end"
end
end
alias rgss_main_no_eval_stack_fix rgss_main
def rgss_main(&proc)
begin
rgss_main_no_eval_stack_fix(&proc)
rescue Exception=>e
p e
e.correct_backtrace if e.respond_to?(:correct_backtrace)
p e.backtrace
raise e
end
end
alias eval_no_stack_fix eval
def eval(script, *args)
eval_no_stack_fix(EvalStackFix.wrap(script), *args)
end[/pre]