Let's say I have an XML::Element...I want to do something like:
my_xml_element.send("parent.next_sibling.next_sibling")
Let's say I have an XML::Element...I want to do something like:
my_xml_element.send("parent.next_sibling.next_sibling")
In your case it's better to use instance_eval
"Test".instance_eval{chop!.chop!} #=> "Te"
And for your code:
my_xml_element.instance_eval{parent.next_sibling.next_sibling}
uh, that's not really what he was asking for if I'm understanding his question correctly. I mean send takes a string or a symbol as an arg, and your solution doesn't. I don't think there's a built in method that will do what you want, but I whipped up a method that will, with a test.
require 'test/unit'
class Example
def multi_send(str)
str.split('.').inject(self){|klass, method| klass.send(method) }
end
end
class MyTest < Test::Unit::TestCase
def test_multi_send
a = Example.new
methods = "class.to_s.downcase.chop!"
assert a.multi_send(methods) == 'exampl'
end
end
I think the question is that you specifically have a series of methods defined as a string, and you want to invoke that on some object, right?
class Object
def call_method_chain(method_chain)
return self if method_chain.empty?
method_chain.split('.').inject(self){|o,m| o.send(m.intern)}
end
end
>> User.first.profile.address.state.name
=> "Virginia"
>> User.first.call_method_chain("profile.address.state.name")
=> "Virginia"
Actually, Khelll was almost right. Use this:
methods_chain = "parent.next_sibling.next_sibling"
result = my_xml_element.instance_eval( eval methods_chain )
This code is up to 20 times faster than using split() and allows you to pass chain methods with args, like this:
methods = "power!(2).div(57).+(12).to_f"
42.instance_eval { eval methods }
The problem with Alfuken's answer based on eval is
A) eval is pretty unsafe although fast
B) if you have an extra (consecutive) dot for method invocation like this
"example".instance_eval{eval "chop!..chop!"}.class
=> "examp".."examp"
"example".instance_eval {eval "chop!..chop!"}.class
=> Range # this is not what is desired