Ruby:打印任意方法的代码(和上下文中的exec)

Sai*_*Sai 1 ruby metaprogramming exec

我想做类似以下的事情:

class String
  def fancy_thing appendix
   # Just a trivial example to ensure self and params work.
   # Pretend this is something complex.
   self.reverse + appendix
  end
end

# print_method on instance or class should spit out a string
#  containing the actual code for that method
ft_code = "cob".print_method :fancy_thing
ft_code = String.print_instance_method :fancy_thing
  # => "{|appendix| self.reverse + appendix }"  *

# ft_code gets passed around a bit...

# exec on an object should run code (w/ parameters) as if that code is 
#  an instance method on that object (or class method if it's a class)
"cob".exec(ft_code, '!') #=> "boc!"
Run Code Online (Sandbox Code Playgroud)

怎么可能有一个代码print_method和foo.exec?优选地,它们应该适用于任何任意方法,而不必事先知道它们可能恰好定义或来源于何处.

  • 是的,我知道方法和块并不完全相同.但这更接近于通常需要的收益和通话; 我不知道更好的解决方案.

jos*_*hng 7

parse_tree将为您提供所需的关键步骤:

http://github.com/seattlerb/parsetree/tree/master

我认为这是以最快/最黑/最不安全的方式做到的:

require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'

class Object
  def method_source(name)
    (class << self; self; end).instance_method(name).to_ruby
  end

  def exec(ruby, *args)
    code = eval(ruby, binding)
    code.call(*args)
  end
end
Run Code Online (Sandbox Code Playgroud)

我要补充一点,我很难看出这是一个好主意......但是你有它.:-)

[编辑]

另请注意,您的示例已被破坏:您的'fancy_thing'方法需要参数(附录).

[编辑2]

超过顶部,这是你的测试代码修复了错误(我认为你想要的方式):

class String
  def fancy_thing(appendix)
    reverse << appendix || nil
  end
end

code = "cob".method_source :fancy_thing
# => "proc {|appendix| reverse << appendix }"  *
"cob".exec code, '!'
# => "boc!"
Run Code Online (Sandbox Code Playgroud)