>>Brian Candler wrote:
>>>o1 = [:defuzz_configs, {"conf"=>"foo.txt"}]
>>>o2 = [:defuzz_configs, {"conf"=>"foo.txt"}]
>>>p o1 == o2 # prints true
>>>p o1.hash == o2.hash # prints false ?? <<<<<<<<<<<
>>That's because the Hashs in o1 and o2 are two different objects.
>
>So hashes and arrays don't behave the same in this regard?
>
>o1 = ["hello", ["world"]]
>o2 = ["hello", ["world"]]
>p o1 == o2
>p o1.hash == o2.hash # prints true
>
>o1 = {"key"=>"hello"}
>o2 = {"key"=>"hello"}
>p o1 == o2
>p o1.hash == o2.hash # prints false
>
>I wonder why this is?
Probably because Hashes store not only key value pairs but also default
value and an optionally block that is invoked if an element is missing
from the Hash.
OK, then I'm missing some subtlety between hash1 == hash2 (which is true),
and hash1.eql? hash2 (which is false).
But given just arrays, and arrays of arrays, array1 == array2 and
array1.eql? array2 are both true. And so is array1.hash == array2.hash
So it appears that someone has decided that hashes cannot be used usefully
as hash keys, but I cannot see why.
The solution
is of course to use your own class for your keys. Since they seem to be
pretty complex that's a good idea anyway.
I solved my problem by doing a linear search over the hash to find the
entry, which seems silly, but it works.
# Was: return @output[input]
@output.each { |(k,v)| return v if k == input }
Making "my own class" was not an option. I was building a small mock object,
and the hash key is whatever method_missing receives. If the caller of the
mock object passes in a hash, then a hash is what I get.
class Mock
def self.prepare(output)
@output = output
end
def self.=(input,output)
@output[input] = output
end
def self.(input)
@output.each { |(k,v)| return v if k == input }
raise "No response for #{input.inspect}"
end
attr_reader :actions
def initialize(*args)
@actions = [[:initialize] + args]
end
def method_missing(*args)
# STDERR.puts "#{args.inspect} => #{self.class[args].inspect}"
@actions << args
self.class[args]
end
end
Mock.prepare({
[:flurble] => 'boo',
})
a = Mock.new(123)
res = a.flurble
p res
p a.actions
Yes, I know there are other mock solutions out there. I would rather just
write something which is (a) small, and (b) does exactly what I need.
Regards,
Brian.
···
On Wed, May 09, 2007 at 06:05:11PM +0900, Robert Klemme wrote:
On 08.05.2007 18:55, Brian Candler wrote:
>On Wed, May 09, 2007 at 12:58:01AM +0900, Sebastian Hungerecker wrote: