【问题标题】:Getting the source of the method that defined dynamically获取动态定义的方法的来源
【发布时间】:2018-03-16 19:01:46
【问题描述】:

如果 any 方法的源代码明确写在文件中,there is 是一个显示代码的简洁方法:

A.instance_method(:foo).source

但如果我在 dynamically 中定义类和方法

Object.const_set(dynamic_name, Class.new { def foo() puts 'bar' end })

我在尝试获取此方法的来源时收到错误,在这种情况下使用instance_method(:foo).source

MethodSource::SourceNotFoundError: Could not load source for : No such file or directory @ rb_sysopen - (eval)

如何获取动态定义方法的来源?有可能吗?

【问题讨论】:

  • 根据gem的文档,有limitations:它“不能返回C方法的源代码”和它“不能返回动态定义方法的源代码” 。所以不,那颗宝石是不可能的。
  • @Stefan,我看到了这个,但没有限制只使用那个 gem
  • 当使用库时,写那个。
  • 完成了,陛下

标签: ruby


【解决方案1】:

至少,您可以获得字节码(假设您使用 MRI)

puts RubyVM::InstructionSequence.disasm(A.instance_method(:foo))
# >> == disasm: #<ISeq:foo@->================================================
# >> 0000 trace            8                                               (   3)
# >> 0002 trace            1
# >> 0004 putself          
# >> 0005 putstring        "bar"
# >> 0007 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
# >> 0010 trace            16
# >> 0012 leave            

【讨论】:

  • 哇。 %) 我希望能找到一个可以返回eval 友好输出的解决方案...
  • @okliv:不,我不会指望那个。
  • 嗯,我的 Rubinius、JRuby、IronRuby 和 Opal 都引发了 no method 错误。
  • @JörgWMittag:他们当然会。 :) 但是没有跨平台的方式,是吗?
  • @JörgWMittag:IIRC,rubinius 有更好的工具。
猜你喜欢
  • 1970-01-01
  • 2019-02-07
  • 2020-11-02
  • 1970-01-01
  • 2020-03-13
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
相关资源
最近更新 更多