从ruby中的yield块跳过迭代

时间:2011-06-20 19:47:08

标签: ruby iteration block yield next

尝试使用一个错误构思的框架,该框架从传入的块中收集结果列表,实际上是这样的:

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 :(得分:0)

坏消息是你必须修补宝石。让gem调用你的代码块不会给你的代码任何特殊的权力来影响调用代码如何处理块的返回值。

好消息是修补宝石通常可以通过“猴子补丁”来完成,你的程序会重新打开宝石的类或模块并进行更改。在这个组成的例子中,我们将展示嵌套在模块中的类,因为许多gem都使用嵌套的类和模块:

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

答案 1 :(得分:0)

没有办法做你想要的。如果您发布有关您正在使用的框架的更多详细信息,那么此处的某些人可能会帮助您想出解决问题的不同方法。

答案 2 :(得分:0)

你需要补丁,就像别人说的那样。如果您想要一个满足某些条件的i集合,最好的选择是将collect替换为find_all,然后您可以使用:

sigh { |i| i == 1 }   #=> [1]