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
···
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.
--
http://ruby.brian-schroeder.de/
Stringed instrument chords: http://chordlist.brian-schroeder.de/