是否有可能在proc中看到ruby代码?

p = Proc.new{ puts 'ok' } 

有可能在proc中看到ruby代码吗?

inspect返回内存位置:

 puts p.inspect # 

Ruby 1.9.3

看看sourcify gem:

 proc { x + y }.to_source # >> "proc { (x + y) }" 

你的意思是原始的源代码或它的字节码表示?

对于前者,您可以使用标准Proc的方法source_location

 p.source_location => ["test.rb", 21] 

并阅读适当的代码行。

对于后者,RubyVM :: InstructionSequence及其类方法可以反汇编:

 irb> RubyVM::InstructionSequence.disasm p => "== disasm:  =====\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, \n0011 leave \n" 

不,没有办法在Ruby中这样做。

某些Ruby实现可能有也可能没有获取源代码的特定于实现的方法。

您还可以尝试使用Proc#source_location查找定义了Proc的文件,然后解析该文件以查找源代码。 但是,如果未在文件中定义Proc (例如,如果它是使用eval动态定义的),或者源文件不再存在,例如因为您正在运行程序的AOT编译版本,那么这将不起作用。

所以,简短的回答是:不,没有办法。 长期的答案是:有些方法可能会或可能不会有效,取决于太多因素甚至开始使这项工作可靠。

这甚至没有考虑到甚至没有 Ruby源代码的Proc ,因为它们是在本机代码中定义的。

如果将proc定义到文件中,U可以获取proc的文件位置然后序列化它,然后在反序列化后使用该位置再次返回proc

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}”)

虽然是一个古老的问题,但我想分享我的想法。

你可以使用Pry gem并最终得到这样的东西:

 [11] pry> p = Proc.new{ puts 'ok' } => # [12] pry> show-source p From: (pry) Number of lines: 1 p = Proc.new{ puts 'ok' } 

此外,如果您将从Rails上下文中使用它,您可以将:

 ::Kernel.binding.pry 

在你的控制器或模型中,和

 - require 'pry'; binding.pry 

在您的视图中,您要开始调试的位置。

在测试中,我使用组合,首先在顶部require 'pry' ::Kernel.binding.pry require 'pry' ,然后在需要的地方需要::Kernel.binding.pry

参考文献: