Reputation: 7209
I would like to do something like the following:
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!"
How might one code print_method and foo.exec? Preferably, they should work for any arbitrary methods, without knowing a priori where they might happen to have been defined or sourced from.
Upvotes: 1
Views: 3019
Reputation: 1540
parse_tree will give you the key step that you'll need:
http://github.com/seattlerb/parsetree/tree/master
I think this does it, in the quickest/hackiest/most insecure manner possible:
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
I'll add that I'm having difficulty seeing how this is a good idea... But there you have it. :-)
[edit]
Also note that your example is busted: your 'fancy_thing' method requires an argument (appendix).
[edit 2]
going over the top, here's your test code with bugs fixed (the way I think you wanted it):
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!"
Upvotes: 7
Reputation: 237060
This isn't very easy to implement without just reading the Ruby file and searching for the method code. In Ruby 1.8, you could use ParseTree and ruby2ruby. In 1.9, I don't know of any solution.
Upvotes: 0