红宝石中的条件链接

时间:2009-11-27 08:45:45

标签: ruby

我已阅读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:在''

3 个答案:

答案 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>
>>