Пропустить итерацию из блока yield в ruby - PullRequest
3 голосов
/ 20 июня 2011

Попытка использовать непродуманную структуру, которая собирает список результатов из переданного блока, эффективно это:

def sigh(&block)
  r = (1..3).collect do |i|
     yield(i)
  end

  # do something with r
end

Я хочу, чтобы блок, который я передаю, фильтровал элементы, но для пропустите итерацию коллекции, а не добавьте nil к результатам, как next (поскольку фреймворк их не уплотняет). Какой простой способ, кроме исправления гема?Т.е.

sigh {|i|  next unless i == 1 }  # results in [1,nil,nil] rather than just [1]

Ответы [ 3 ]

0 голосов
/ 25 января 2012

Нет способа сделать то, что вы просите. Однако, если вы опубликуете более подробную информацию об используемой платформе, кто-то здесь сможет помочь вам придумать другой способ решения проблемы.

0 голосов
/ 27 января 2012

Вам нужно будет патчить, как говорили другие. Если вы хотите коллекцию i, которая удовлетворяет некоторому условию, лучшим выбором будет заменить collect на find_all, и тогда вы можете использовать:

sigh { |i| i == 1 }   #=> [1]
0 голосов
/ 21 июня 2011

Плохая новость в том, что вам придется исправлять камень. То, что ваш блок кода вызван гемом, не дает вашему коду особых возможностей влиять на то, как вызывающий код обрабатывает возвращаемые значения блока.

Хорошей новостью является то, что исправление драгоценного камня обычно можно выполнить с помощью «обезьяньего заплатки», когда ваша программа повторно открывает класс или модуль драгоценного камня и вносит изменения. В этом готовом примере мы покажем класс, вложенный в модуль, поскольку многие гемы используют вложенные классы и модули:

require 'somegem'

# Monkey patch to cause Somegem's do_something_cool method
# to ignore the SomethingBadHappened exception

module SomeGem
  class SomeClass
    alias_method :orig_do_something_cool, :do_something_cool
    def do_something_cool
      orig_do_something_cool
    rescue SomethingBadHappened
    end
  end
end
...