必须有一种内置的方法,对吗?
class Object
def send_chain(arr)
o=self
arr.each{|a| o=o.send(a) }
return o
end
end
答案 0 :(得分:57)
我刚碰过这个,它真的很想注入:
def send_chain(arr)
arr.inject(self) {|o, a| o.send(a) }
end
答案 1 :(得分:6)
不,不是内置方式来执行此操作。你所做的简单而简洁,更不用说危险了。使用时要小心。
另一个想法是,这可以扩展到接受参数:
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
这可以让你在一个数组中传递一个带有参数的方法名,比如;
test = MyObject.new
test.send_chain :a_method, [:a_method_with_args, an_argument, another_argument], :another_method
答案 2 :(得分:4)
根据以前的答案,如果您需要将参数传递给每个方法,可以使用:
def send_chain(arr)
Array(arr).inject(self) { |o, a| o.send(*a) }
end
然后您可以使用以下方法:
arr = [:to_i, [:+, 4], :to_s, [:*, 3]]
'1'.send_chain(arr) # => "555"
此方法也接受单个参数。
答案 3 :(得分:0)
如何在不污染Object
类的情况下实现这种多功能解决方案:
def chain_try(arr)
[arr].flatten.inject(self_or_instance, :try)
end
或
def chain_send(arr)
[arr].flatten.inject(self_or_instance, :send)
end
通过这种方式,可以同时使用Symbol
,String
或Array
以及两者的混合。?
用法示例:
chain_send([:method1, 'method2', :method3])
chain_send(:one_method)
chain_send('one_method')