Ruby: How to chain multiple method calls together with "send"
There has to be a built in way of doin开发者_运维技巧g this, right?
class Object
def send_chain(arr)
o=self
arr.each{|a| o=o.send(a) }
return o
end
end
I just ran across this and it really begs for inject:
def send_chain(arr)
arr.inject(self) {|o, a| o.send(a) }
end
Building upon previous answers, in case you need to pass arguments to each method, you can use this:
def send_chain(arr)
Array(arr).inject(self) { |o, a| o.send(*a) }
end
You can then use the method like this:
arr = [:to_i, [:+, 4], :to_s, [:*, 3]]
'1'.send_chain(arr) # => "555"
This method accepts single arguments as well.
No, there isn't a built in way to do this. What you did is simple and concise enough, not to mention dangerous. Be careful when using it.
On another thought, this can be extended to accept arguments as well:
class Object
def send_chain(*args)
o=self
args.each do |arg|
case arg
when Symbol, String
o = o.send arg # send single symbol or string without arguments
when Array
o = o.send *arg # smash the inner array into method name + arguments
else
raise ArgumentError
end
end
return o
end
end
this would let you pass a method name with its arguments in an array, like;
test = MyObject.new
test.send_chain :a_method, [:a_method_with_args, an_argument, another_argument], :another_method
How about this versatile solution without polluting the Object
class:
def chain_try(arr)
[arr].flatten.inject(self_or_instance, :try)
end
or
def chain_send(arr)
[arr].flatten.inject(self_or_instance, :send)
end
This way it can take a Symbol
, a String
or an Array
with a mix of both even.
精彩评论