Sam Roberts <sroberts@xxxxxxxxxxxx> writes:
> I've tried:
>
>
> h = { }
>
> k = 'a'
>
> class << k
> def hash; self.downcase.hash; end
> def ==(s); self.downcase == s.downcase; end
> def eql?(s); self == s; end
> def ===(s); self == s; end
> end
>
> k = 'A'
>
> class << k
> def hash; self.downcase.hash; end
> def ==(s); self.downcase == s.downcase; end
> def eql?(s); self == s; end
> def ===(s); self == s; end
> end
>
> k == 'a'
> k.hash == 'a'.hash
>
> # I want this to be true!
> h.has_key? k
>
> But it doesn't work. I'm particularly confused because if I write a
> class Str that wraps String and defines those methods things do work
> out...
>
> Any pointers?
This looks like a consequence of the fact that when ruby takes the
hash of a key, if the key is a String, it uses the default
implementation of String#hash directly, even if String#hash has been
redefined, or the object has a singleton class. (The same thing is
true with Fixnums and Symbols.)
Try:
class String
def hash
puts '!'
super
end
end
{}['a'] = 1
Then change the String to an Object.
HTH.
|