5

ボイラープレートベンチマークコードを作成するために、列挙可能なブロック内で譲歩できるようにしたいと思います。

基本的に私はこれ(簡略化)で何かをしたいです:

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...

このようなことは可能であるに違いないようですが、構文も、(それを調べるために)そのようなものが何と呼ばれるのかを理解することができませんでした。

問題は、反復する列挙可能なオブジェクトの外側と、反復ブロックの内側の両方でボイラープレートをラップする必要があることです。列挙可能なオブジェクトを問題なく渡すことはできますが、渡すブロック内から反復オブジェクトのメソッドを呼び出すことができないようです。

この説明が理にかなっていることを願っています、私はそれを説明するのに苦労しています。何か説明が必要な場合はコメントを残してください。もっとよく説明しようと思います。

4

1 に答える 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
于 2011-07-30T00:13:56.853 に答える