Multiple responses below: On Sunday 10 October 2004 03:59 pm, Florian Gross wrote: | > def each | > seed = @start | | @step ||= 1.0 / 0.0 # Infinity | @step.times do | yield(seed) | @skip.times { seed = seed.succ } | break if @halt and @halt.call(seed) | | > end | > end This one blew-up on 1.8.2, no Float#times :( | And maybe this: (in case @start is numeric) | | def each | (@start .. (1.0 / 0.0)).step(@skip) do |seed| | yield(seed) | break if @halt and @halt.call(seed) | end | end Oh the irony here! It sort of uses what I'm rewriting ;) Thanks. --- On Sunday 10 October 2004 04:03 pm, Mikael Brockman wrote: | You could let @step default to $infinity, where $infinity is something | | like this: | | $infinity = Object.new | | class << $infinity | | def times; loop { yield }; end | | # other infinity methods omitted because YAGNI | | end | | That would let you define #each as simply | | | def each | | seed = @start | | @step.times do | | yield(seed) | | @skip.times { seed = seed.succ } | | break if @halt.call(seed) if @halt | | end | | end and On Sunday 10 October 2004 05:36 pm, Markus wrote: | > end | | How about: | | Forever = Object.new | def Forever.times | loop {yield} | end | | def each | seed = @start | (@step || Forever).times do | yield(seed) | @skip.times { seed = seed.succ } | break if @halt.call(seed) if @halt | end | end These two are similar. And I'm sure I'd go this way if Infinite/Forever were a standard class, and yet I may go this route anyway. Hmm... may be an interesting place to use one of those method procs: forever = proc(:times){|&blk| blk.call} (1.9 only I think) Just a thought. Thanks. --- On Sunday 10 October 2004 03:51 pm, Alexey Verkhovsky wrote: | On Sun, 2004-10-10 at 22:25, trans. (T. Onoma) wrote: | > Notice the three lines of duplication. Any ideas on DRYing this up? | | I would extract them into a method. | | Another alternative, at a price of checking @step on every iteration, | and much less readable than your original: | | # UNTESTED | | def each | seed = @start | counter = 0 | loop do | break if @step and (counter += 1) > step | yield(seed) | @skip.times { seed = seed.succ } | break if @halt.call(seed) if @halt | end | end and On Sunday 10 October 2004 03:59 pm, Randy W. Sims wrote: | loop do | break if @step && (@step -= 1) < 0 | yield(seed) | @skip.times { seed = seed.succ } | break if @halt.call(seed) if @halt | end Extra break. I bet this would be the thing to do if using a lower level language. Using Ruby though, I'm guessing other means are more efficient. You concur? Thanks. --- On Sunday 10 October 2004 05:55 pm, Mauricio Fernández wrote: | On Mon, Oct 11, 2004 at 04:25:30AM +0900, trans. (T. Onoma) wrote: | > Notice the three lines of duplication. Any ideas on DRYing this up? | > | > def each | > seed = @start | | Am I the only one who sometimes does things resembling | whatever = lambda do | yield(seed) | @skip.times { seed = seed.succ } | break if @halt.call(seed) if @halt | end | and then whatever[] ?? | and On Sunday 10 October 2004 06:14 pm, Jamis Buck wrote: | Glad you mentioned this, batsman. I was just about to. Let me fill in | the blank at the end of your example, though, since I'm the type of guy | that just can't stand a song only partially sung... | | @step ? @step.times(&whatever) : loop(&whatever) This was my thought too. But when I did it that way I thought maybe I was loosing a little efficiency assigning and calling the proc, and wondered if there were any better ways, but maybe not. --- Thanks everyone. Let you know what I settle on. T.