रूबी ट्रेसबैक में मैं स्रोत और परिवर्तनीय मान कैसे प्राप्त कर सकता हूं? - रूबी, डीबगिंग, अपवाद, ट्रेसबैक

यहां रेल ट्रेसबैक पर एक सामान्य रूबी के अंतिम कुछ फ्रेम हैं: आवेदन ट्रेस http://img444.imageshack.us/img444/8990/rails-lastfew.png

और यहां पाइथन में एक विशिष्ट नेवो ट्रेसबैक के आखिरी कुछ फ्रेम हैं: alt text http://img444.imageshack.us/img444/9173/nw-lastfew.png

यह सिर्फ वेब वातावरण ही नहीं है, आप ipython और irb के बीच समान तुलना कर सकते हैं। रूबी में मुझे इस प्रकार के विवरणों को और अधिक कैसे प्राप्त किया जा सकता है?

उत्तर:

उत्तर № 1 के लिए 7

AFAIK, एक बार एक अपवाद पकड़ा गया है यह भी हैउस संदर्भ को पकड़ने में देर हो गई जिसमें इसे उठाया गया था। यदि आप अपवाद के नए कॉल को फँसते हैं, तो आप कॉलिंग स्कोप को पकड़ने के लिए evil.rb "s बाइंडिंग.of_caller का उपयोग कर सकते हैं, और करते हैं

eval("local_variables.collect { |l| [l, eval(l)] }", Binding.of_caller)

लेकिन वह काफी बड़ा हैक है।कॉल स्टैक के कुछ निरीक्षण की अनुमति देने के लिए सही जवाब शायद रुबी का विस्तार करना है। मुझे यकीन नहीं है कि कुछ नए रूबी कार्यान्वयन इस बात की अनुमति देंगे, लेकिन मुझे बाध्यकारी.of_caller के खिलाफ एक प्रतिक्रिया याद है क्योंकि यह अनुकूलन को अधिक कठिन बना देगा।

(ईमानदार होने के लिए, मैं इस प्रतिक्रिया को समझ नहीं पा रहा हूं:जब तक दुभाषिया प्रदर्शन किए गए अनुकूलन के बारे में पर्याप्त जानकारी रिकॉर्ड करता है, तब तक Binding.of_caller काम करने में सक्षम होना चाहिए, हालांकि शायद धीरे-धीरे।)

ठीक है, मैंने पता लगा लिया। लांगिश कोड निम्नानुसार है:

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

संबंधित सवाल
सबसे लोकप्रिय