условная цепочка в рубине - PullRequest
1 голос
/ 27 ноября 2009

Я прочитал этот вопрос , но я не смог создать полный пример:

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: в `каждом '

из inject_ex.rb: 26: в `inject '

из inject_ex.rb: 26: в `'

Ответы [ 3 ]

4 голосов
/ 27 ноября 2009

Inject передает возвращаемое значение блока на следующую итерацию. Теперь ваш obj имеет возвращаемое значение obj.send(:method_a) после первой итерации. Исправьте инъекцию так:

l.inject(some) { |obj, method|
  obj.send(method)
  obj
}
3 голосов
/ 27 ноября 2009

Вы также можете использовать 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}
1 голос
/ 27 декабря 2009

tap - метод add в ruby ​​1.9. Но мы можем использовать метод возврата в Rails в ruby ​​1.8. Код консоли 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>
>> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...