我已阅读this question,但我无法创建完整的示例:
class Some
def method_a
puts "a"
end
def method_b
puts "b"
end
def method_c
puts "c"
end
end
some = Some.new
a = true
b = true
c = true
l = []
l << :method_a if a
l << :method_b if b
l << :method_c if c
l.inject(some) { |obj, method|
obj.send(method)
}
[demas @ arch.local.net] [〜/ dev / study / ruby / oop]%ruby inject_ex.rb
一个inject_ex.rb:26:在
block in <main>': undefined method
method_b'中为nil:NilClass(NoMethodError)
来自inject_ex.rb的:26:在'each'
中来自inject_ex.rb:26:在`inject'
来自inject_ex.rb:26:在''
答案 0 :(得分:4)
Inject将块的返回值传递给下一次迭代。现在,您的obj
在第一次迭代后的返回值为obj.send(:method_a)
。修复你的注入:
l.inject(some) { |obj, method|
obj.send(method)
obj
}
答案 1 :(得分:3)
您也可以使用tap
:
l.inject(some) do |obj,method|
obj.tap{|o| o.send(method)}
end
或者您可以使用点击来摆脱l
:
some.tap{|s|s.method_a if a}.tap{|s|s.method_b if b}.tap{|s|s.method_c if c}
答案 2 :(得分:1)
tap是添加ruby 1.9的方法。但是我们可以在ruby 1.8中使用Rails中的返回方法。 Rails控制台代码:
>> class Some
>> def method_a
>> puts "a"
>> end
>>
?> def method_b
>> puts "b"
>> end
>>
?> def method_c
>> puts "c"
>> end
>> end
=> nil
>>
?> some = Some.new
=> #<Some:0x2a98c4f938>
>>
?> a = true
=> true
>> b = true
=> true
>> c = true
=> true
>>
?> l = []
=> []
>> l << :method_a if a
=> [:method_a]
>> l << :method_b if b
=> [:method_a, :method_b]
>> l << :method_c if c
=> [:method_a, :method_b, :method_c]
>> l.inject(some){|obj, method| returning(obj){|r| r.send method}}
a
b
c
=> #<Some:0x2a98c4f938>
>>