在ruby中从屈服块跳过迭代

在ruby中从屈服块跳过迭代,ruby,iteration,block,yield,next,Ruby,Iteration,Block,Yield,Next,试图使用一个构思不周的框架,从传入的块中收集结果列表,实际上: def sigh(&block) r = (1..3).collect do |i| yield(i) end # do something with r end 我希望我传入的块可以过滤项目,但是要跳过收集迭代,而不是像next那样将nil添加到结果中(因为框架没有压缩它们)。除了修补gem之外,还有什么简单的方法?即 sigh {|i| next unless i == 1 } # resu

试图使用一个构思不周的框架,从传入的块中收集结果列表,实际上:

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

  # do something with r
end
我希望我传入的块可以过滤项目,但是要跳过收集迭代,而不是像
next
那样将
nil
添加到结果中(因为框架没有压缩它们)。除了修补gem之外,还有什么简单的方法?即

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

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

好消息是,修补gem通常可以通过一个“猴子补丁”来完成,您的程序可以重新打开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

没有办法做你要求的事。但是,如果您发布更多关于您正在使用的框架的详细信息,这里的某人可能会帮助您想出一种不同的解决问题的方法。

您需要像其他人所说的那样进行修补。如果您想要满足某些条件的
i
集合,最好的选择是将
collect
替换为,然后您可以使用:

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

我感觉到你的未来有一块猴子补丁,简单的“叹气{I{next,除非I==1}.compact”有什么问题?太冗长了?我需要将一个块传递到框架方法
sigh
,该方法过滤框架随后作用的结果。在结果中抛出
nil
。我现在看到了被问到的问题。我想不出一个办法
break
将从整个方法中退出。@Wayne:除非它是开源的gem,在这种情况下,最好的monkey补丁可能是pull请求。