Levin Alexander wrote:
> Hi,
>
> I just got an Exception that I found somewhat confusing:
>
>    $ ruby -e "puts((1..10).include?('a'))"
>    true
>
>    $ ruby -e "puts(('a'..'z').include?(1))"
>    -e:1:in `include?': undefined method `>' for false:FalseClass
> (NoMethodError)
>    	from -e:1
>
>    $ ruby -v
>    ruby 1.8.2 (2004-12-23) [i386-linux]
>
> Is there a reason for this behaviour?
>
> Thank You,
> Levin

This is a bug with the String#<=>.  It has been discussed on Ruby talk
before, but at some point something similar to the following is
happening:
irb(main):001:0> 'a' <=> 1
=> false
irb(main):002:0> ('a' <=> 1) > 0
NoMethodError: undefined method `>' for false:FalseClass
        from (irb):2

'a' <=> 1 should return nil in this situation.

See:
  range_include() in range.c
  rb_str_cmp_m() in string.c
  rb_cmpint() in compar.c

I think this is changed in Ruby 1.9, but you could do something like
the following:

$ cat s.rb
p 'a' <=> 1
class String
        alias old_cmp <=>
        def <=>(v)
                return nil unless v.is_a? String
                return old_cmp(v)
        end
end
p 'a' <=> 1
p ('a'..'z').include?(1)

$ ruby s.rb
false
nil
false

$ ruby -v
ruby 1.8.2 (2004-12-25) [i386-cygwin]

-Charlie