On 25/10/05, Christophe Grandsire <christophe.grandsire / free.fr> wrote:
> Selon Warren Seltzer <warrens / actcom.net.il>:
>
> > The following failure surprised me:
> >
> > Version 1:
> >
> > irb(main):068:0> "hi".class == "hi".class
> > => true
> > irb(main):069:0> "hi".class === "hi".class
> > => false
> >
> >
> > Version 2:
> >
> > irb(main):055:0> case "whatever".class
> > irb(main):056:1> when String
> > irb(main):057:1>   p "it is a string"
> > irb(main):058:1> else
> > irb(main):059:1*  p "it is not a string"
> > irb(main):060:1> end
> > "it is not a string"
> >
> > What it amounts to is you can't use case/when to test for class.  This is a
> > HUGE LOSE.
> > The pickaxe book .chm says YOU CAN do it.  I'm using ruby 1.8.2
> >
>
> Lose the ".class". === automatically looks for the class of the left argument.
> In your case example, just write:
> case "whatever"
> when String
>   p "it is a string"
> else
>   p "it is not a string"
> end
>
> It's work like a charm. Basically "a === SomeClass" is the same as "a.class ==
> SomeClass".
> --
> Christophe Grandsire.
>
> http://rainbow.conlang.free.fr
>
> It takes a straight mind to create a twisted conlang.
>

Just throwing in that it would not be a "BIG LOSS", not even a _big
loss_ or a big loss, because you nearly never should test for the
class of an object.

bschroed@black:~/svn/projekte/ruby-things$ cat undef.rb
class UppercaseString
  def initialize(string)
    @string = string.upcase
  end

  def gsub(*args, &block)
    self.class.new(@string.gsub(*args, &block))
  end

  def to_s
    @string.dup
  end
end

a = "quack like a duck"
b = UppercaseString.new("walk like a duck")

puts a.gsub(/duck/i, 'cow')

puts b.gsub(/duck/i, 'cow')

class <<a
  undef_method "gsub"
end
puts a.gsub(/0*/, '42')
bschroed@black:~/svn/projekte/ruby-things$ ruby undef.rb
quack like a cow
WALK LIKE A COW
undef.rb:25: undefined method `gsub' for "quack like a duck":String
(NoMethodError)


now imagine require would have been implemented like this:

def require(filename)
  case filename
  when String
    load filename.gsub('\\', '/')
  when Symbol
    require(filename.to_s)
  when Fixnum
    raise "Can require only once"
  else
    raise "Don't know what to do"
  end
end

Then require would only work with real strings and symbols but not
with our stringlike new class. And with strings that behave special
(like our a) it would not work. So always use respond_to? instead of a
class test.

Maybe I should have used a standard ducktyping example, my own is a
bit week, but I hope it help.

cheers,

Brian


--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/