From: Jamis Buck Date: 2004-10-11T10:58:05+09:00 Subject: Re: Putting some code out to DRY trans. (T. Onoma) wrote: > 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. Try some benchmarks. I've found I'm nearly always wrong in what I assume to efficient vs. inefficient in Ruby, and benchmarks are usually trivial to write: require 'benchmark' class Test def initialize( start, step, skip, &halt ) @start = start @step = step @skip = skip @halt = halt end def each1 seed = @start if @step @step.times do yield(seed) @skip.times { seed = seed.succ } break if @halt.call(seed) if @halt end else loop do yield(seed) @skip.times { seed = seed.succ } break if @halt.call(seed) if @halt end end end def each2 seed = @start whatever = lambda do yield(seed) @skip.times { seed = seed.succ } return if @halt.call(seed) if @halt end @step ? @step.times(&whatever) : loop(&whatever) end end Benchmark.bm do |x| with_step = Test.new( 1, 100000, 1 ) without_step = Test.new( 1, nil, 1 ) { |s| s > 100000 } x.report { with_step.each1 { |s| } } x.report { without_step.each1 { |s| } } x.report { with_step.each2 { |s| } } x.report { without_step.each2 { |s| } } end Turns out, the two approaches are virtually identical in execution times: user system total real 0.200000 0.000000 0.200000 ( 0.233535) 0.370000 0.000000 0.370000 ( 0.428697) 0.200000 0.000000 0.200000 ( 0.239925) 0.370000 0.000000 0.370000 ( 0.405779) - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis