I'd like to be able to yield within an enumerable block, in order to create some boilerplate benchmarking code.
Basically I'd like to do something this (simplified):
def iterator( enumerable, &block )
iterations = enumerable.size
counter = 0
enumerable.each do |item|
counter +=1
puts "Iterating #{counter}/#{iterations}..."
yield
end
end
Then I'd like to be able to use this method in order to wrap this boilerplate benchmarking code around a block I would be iterating, so that I could call something like:
# assuming foo is an enumerable collection of objects
iterator foo do
item.slow_method
item.mundane_method
item.save
end
... and when this code executed I would get the following log output:
Iterating 1/1234...
Iterating 2/1234...
Iterating 3/1234...
It seems like this kind of thing must be possible, but I haven't been able to figure out the syntax, nor what such a thing is called (in order to look it up).
The problem is I need to wrap boilerplate both OUTSIDE the enumerable object that is going to iterate, and also INSIDE the iteration block. I can pass an enumerable object in just fine, but I can't seem to call methods on the iterated objects from within the block I pass in.
I hope this explanation makes sense, I'm having a hard time describing it. Please leave comments if you need clarification on anything, I'll try to explain better.
Ruby's yield
statement can take arguments. You would want to say
yield item
This passes the "current" item to your "outside" block.
Hope I understood the question correctly.
ADDENDUM
And here is the code to show it in action:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With