在Ruby中跳过yield块的迭代

wydwbb8l  于 2023-05-28  发布在  Ruby
关注(0)|答案(3)|浏览(161)

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

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

  # do something with r
end

我希望我传入的块过滤项目,但要 * 跳过 * 集合迭代,而不是像next那样将nil添加到结果中(因为框架不会压缩它们)。即,

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

kgsdhlau1#

坏消息是你必须修补宝石。让gem调用您的代码块并不会给予您的代码任何特殊的权力来影响调用代码如何处理块的返回值。
好消息是,修补gem通常可以使用“monkey patch”完成,在这个补丁中,程序重新打开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
1wnzp6jl

1wnzp6jl2#

没有办法做到你所要求的。如果你发布了更多关于你正在使用的框架的细节,这里的人可能会帮助你想到一种不同的方法来解决这个问题。

rqqzpn5f

rqqzpn5f3#

你需要补一下,就像其他人说的。如果你想要一个满足某些条件的i的集合,最好的选择是用find_all替换collect,然后你可以用途:

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

相关问题