Bugs item #9488, was opened at 2007-03-23 11:02 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1698&aid=9488&group_id=426 Category: Standard Library Group: None Status: Open Resolution: None Priority: 3 Submitted By: Colin Bartlett (colinb2) Assigned to: Nobody (None) Summary: Date module, step method, infinite loop if +step+ is 0 ? Initial Comment: My apologies in advance if this is known about. I have looked at the outstanding "bugs" list, and couldn't find anything. I'm using the standard Ruby Installer for Windows Ruby Version 1.8.5, Installer Version 185-21 ruby --version -> ruby 1.8.5 (2006-08-25) [i386-mswin32] code of the step method in Tadayoshi Funaba's Date module # Step the current date forward +step+ days at a # time (or backward, if +step+ is negative) until # we reach +limit+ (inclusive), yielding the resultant # date at each step. def step(limit, step) # :yield: date da = self op = [:-,:<=,:>=][step<=>0] while da.__send__(op, limit) yield da da += step end self end Comment: the step method seems to go into an infinite loop if +step+ is 0, continually yielding the start date (self). I didn't instantly understand the "op = " and "while" lines, but I think I understand them now, except if +step+ is 0 then the while expression becomes ( da - limit ), which is always going to be True because even if it's 0 it will be True? Is that why the infinite loop is happening? Is an infinite loop the intended behaviour if +step+ is 0 ? Or is the intention for people to rely on testing not to use a +step+ of 0? (That's not intended to be sarcastic: I don't know enough to be sure the behaviour is not as intended.) In the Integer step method a +step+ of 0 raises an exception, which seems a better way to handle it? (Maybe have an option of yielding (only once) the start date if +step+ is 0 ? On reflection I think I still prefer the Integer step behaviour.) # The following is code to show the different behaviour # of Integer step and Date step when +step+ is 0. $\ = " " ; $, = " " # helps print output legibly on single lines puts "\n ** Integer step example: exception raised if step = 0" 500.step( 505, 2 ) { | nxt | print nxt } # -> 500 502 504 50.step( 45, -2 ) { | nxt | print nxt } # -> 50 48 46 begin 5.step( 5, 0 ) { | nxt | puts nxt } rescue puts ' * exception raised: message = ' + $!.message end # -> * exception raised: message = step can't be 0 require 'date' c = Date.new( 2008, 1, 31 ) puts "\n\n ** Date step example:" + " no error if step = 0, but an infinite loop?" c.step( c + 3, 2 ) { | nxt | print nxt } # -> 2008-01-31 2008-02-02 c.step( c - 3, -2 ) { | nxt | print nxt } # -> 2008-01-31 2008-01-29 puts count = 0 c.step( c + 3, 0 ) { | nxt | puts count.to_s + ": " + nxt.to_s count += 1 break if count > 10 } # -> "infinite" loop of 2008-01-31 ? ---------------------------------------------------------------------- >Comment By: Colin Bartlett (colinb2) Date: 2007-03-23 11:10 Message: My original example used c.step( c, 0 ) but for the "bug" report I changed it to c.step( c + 3, 0 ) without testing it. (A bad idea.) If using c.step( c + 3, 0 ) doesn't show the Date step behaviour if +step+ is 0, then please try my original example. ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1698&aid=9488&group_id=426