p = Proc.new{ puts 'ok' }
请问在proc中能看到Ruby代码吗?
inspect
会返回内存位置:
puts p.inspect
#<Proc:0x007f9e42980b88@(irb):2>
Ruby 1.9.3
看一下 sourcify gem:
proc { x + y }.to_source
# >> "proc { (x + y) }"
source_location
。p.source_location
=> ["test.rb", 21]
irb> RubyVM::InstructionSequence.disasm p
=> "== disasm: <RubyVM::InstructionSequence:block in irb_binding@(irb)>
=====\n== catch table\n| catch type: redo st: 0000 ed: 0011 sp: 0000
cont: 0000\n| catch type: next st: 0000 ed: 0011 sp: 0000 cont:
0011\n|------------------------------------------------------------------------\n
0000 trace 1
( 1)\n0002 putself \n0003 putstring \"ok\"\n0005
send :puts, 1, nil, 8, <ic:0>\n0011 leave \n"
RubyVM
是 YARV 的非标准扩展。它不是 Ruby 语言规范的一部分。MRI 没有它,Rubinius 没有它,MagLev 没有它,JRuby 没有它,IronRuby 没有它。我宁愿不依赖于仅适用于单个 Ruby 实现的东西。 - Jörg W Mittag虽然这是一个老问题,但我仍想分享我的想法。
您可以使用Pry gem,最终得到类似于以下内容:
[11] pry> p = Proc.new{ puts 'ok' }
=> #<Proc:0x007febe00e6360@(pry):23>
[12] pry> show-source p
From: (pry)
Number of lines: 1
p = Proc.new{ puts 'ok' }
::Kernel.binding.pry
- require 'pry'; binding.pry
在您的观点中,您希望从哪里开始调试。
在测试中,我使用了一种组合方式,首先在顶部添加require 'pry'
,然后在需要的地方添加::Kernel.binding.pry
。
参考:
反序列化后:proc_location_array = proc.source_location
file_name = proc_location_array[0]
line_number = proc_location_array[1]
proc_line_code = IO.readlines(file_name)[line_number - 1]
proc_hash_string = proc_line_code[proc_line_code.index("{")..proc_line_code.length]
proc = eval("lambda #{proc_hash_string}")