On 5/3/06, Rob Burrowes <rob / cs.auckland.ac.nz> wrote: > Hmmm, it works if I bracket the range. Why is that? I came to the same result as others. I also figured out why you were getting that weird behavior when using the if statement. Let's take a simple test: 3 in 2...5? In irb: >> 2...5 === 3 ArgumentError: bad value for range >> (2...5) === 3 => true Looks right, 5 === 3 was binding first, so in the first case we really had 2...false (since 5 === 3 is false). To verify: >> 2...false ArgumentError: bad value for range So why doesn't this code: [1,2,3,4,5,6,7,8,9,10].each do |x| puts x if 2...5 === x end raise that exception? If I use select instead, it "works": >> [1,2,3,4,5,6,7,8,9,10].select{ |x| 2...5 === x } ArgumentError: bad value for range The key is the binding again, let's look at that line with the condition again: puts x if 2...5 === x This is the same as puts x if 2...(5 === x) And since the default Object#===, which isn't overriden by the time we reach Integer, returns false, we have: puts x if 2...false regardless of x. Now, if 2...false meant a range, like it did other times, the Range constructor would raise the expected exception. *But*, this syntax appears as the condition of an if statement and the special meaning of the ... comes into play. Since 2 never "matches" (I think it uses the Object#=~ method here?), the switch is never turned on. Whew! Jacob Fugal