Ruby中的可枚举对象:yield关键字

5

我希望能够在可枚举块中使用yield,以便创建一些样板式的基准测试代码。

基本上,我想要做这样的事情(简化):

def iterator( enumerable, &block )
  iterations = enumerable.size
  counter = 0
  enumerable.each do |item|
    counter +=1
    puts "Iterating #{counter}/#{iterations}..."
    yield
  end
end

接下来我想使用这种方法,将这个样板基准测试代码包装在我要迭代的块周围,以便我可以调用类似以下内容的东西:

# assuming foo is an enumerable collection of objects
iterator foo do
  item.slow_method
  item.mundane_method
  item.save
end

当执行此代码时,我会得到以下日志输出:
Iterating 1/1234...
Iterating 2/1234...
Iterating 3/1234...

似乎这种事情一定是可以实现的,但我无法弄清语法,也不知道这种东西叫什么(以便查找)。
问题在于,我需要将模板代码包装在枚举对象的外部和迭代块的内部。我可以很好地传递一个可枚举对象,但似乎无法从我传入的块中调用迭代对象的方法。
希望这个解释说得通,我很难描述它。如果您需要任何澄清,请留下评论,我会尽力解释清楚。

你可能想使用 enumerable.zip(1..size).each do |item, counter| 来编写“更简洁”的代码。 - Andrew Grimm
1个回答

7
Ruby的yield语句可以带有参数。你可能想这样说:
yield item

这将“当前”项传递给你的“外部”块。
希望我正确理解了问题。
补充说明:
以下是展示它的代码:
class Item
  def initialize(id)
    @id = id
  end
  def slow_method()
    puts "slow #@id"
  end
  def mundane_method()
    puts "mundane #@id"
  end
  def save()
    puts "save #@id"
  end
end

foo = [Item.new(100), Item.new(200), Item.new(300)]

def iterator(enumerable, &block)
  iterations = enumerable.size
  counter = 0
  enumerable.each do |item|
    counter +=1
    puts "Iterating #{counter}/#{iterations}..."
    yield item
  end
end

iterator foo do |item|
  item.slow_method
  item.mundane_method
  item.save
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接