Experimenting with changing a class’ behaviour when used as a hash key…

Download this source

class Dclz
  @str = "A string"
  attr_reader :str

  # Hashes use eql? and hash to compare keys.
  def eql?(o)
    self.str == o.str
  end

  # Make it behave as expected
  alias :== :eql?

  # Casecmp - defining lets us use in 'case' 
  # statements.
  def ===(o)
    self.str === o.str
  end
  
  def hash
    self.str.hash
  end
end

# In case
case Dclz.new
when Dclz.new
  puts "Works"
else
  puts "doesn't"
end                                   # => "Works"

# Hash with default 'failure' value.
h = Hash.new { "Failure" }
h[d = Dclz.new] = "Expected"

puts Dclz.new == Dclz.new             # => true
puts Dclz.new.hash == Dclz.new.hash   # => true

puts h[d]                             # => "Expected"
puts h[Dclz.new]                      # => "Expected"
puts h["nonkey"]                      # => "Failure"

Running this outputs:

Works
true
true
Expected
Expected
Failure