TheYAML change the id of Object


#1

I’m using an hash object and i use a Termine Object for the key and, for
now, a String for the value.
The class Termine is this:

class Termine
DEFAULT_LANG = “it”
attr_accessor :descrizione
attr_accessor :lingua
def initialize(descrizione="", lingua=DEFAULT_LANG)
@descrizione = descrizione
@lingua = lingua
end
end

In my test file all is good (compare, edit, delete and reference), but
if I dump all in a file YAML and then I load the file YAML the equal
assertion have a failure.
The attributes ‘descrizione’ and ‘lingua’ on the key are the same, but
the problem is that the id of the object is changed… and so there is
the failure.

test_yaml: before hash dump
#Termine:0x2ada6a8:Key T4 in lingua it – Value: Definizione uno
#Termine:0x2ada720:Key T3 in lingua it – Value: Definizione tre
#Termine:0x2ada750:Key T2 in lingua it – Value: Definizione due
#Termine:0x2ada780:Key T1 in lingua it – Value: Definizione uno

test_yaml: after dump (is clear)

test_yaml: after load
#Termine:0x2ad6400:Key T4 in lingua it – Value: Definizione uno
#Termine:0x2ad5f20:Key T3 in lingua it – Value: Definizione tre
#Termine:0x2ad5a40:Key T2 in lingua it – Value: Definizione due
#Termine:0x2ad5518:Key T1 in lingua it – Value: Definizione uno

How can I solve this problem?

Thanks to all for the help…
–Andrea.


#2

On Dec 19, 2005, at 9:10 AM, Andrea wrote:

  @descrizione = descrizione

#Termine:0x2ad5f20:Key T3 in lingua it – Value: Definizione tre

You need to overload the == operator and the hash method.

class Termine
alias eql? ==
def ==(other)
descrizione == other.descrizione and lingua == other. lingua
end
def hash
(descrizione + lingua).hash
end
end

t = Termine.new(“Hi”)
t2 = Termine.new(“Hi”)

t == t2 #=> true

h = {}
h[t] = “short hello”
h #=> {#<Termine:0x24a22c @lingua=“it”, @descrizione=“Hi”>=>“short
hello”}
h.has_key?(t2) #=> true


#3

Logan C. wrote:

On Dec 19, 2005, at 9:10 AM, Andrea wrote:

  @descrizione = descrizione

#Termine:0x2ad5f20:Key T3 in lingua it – Value: Definizione tre

You need to overload the == operator and the hash method.

class Termine
alias eql? ==
def ==(other)
descrizione == other.descrizione and lingua == other. lingua
end
def hash
(descrizione + lingua).hash
end
end

t = Termine.new(“Hi”)
t2 = Termine.new(“Hi”)

t == t2 #=> true

h = {}
h[t] = “short hello”
h #=> {#<Termine:0x24a22c @lingua=“it”, @descrizione=“Hi”>=>“short
hello”}
h.has_key?(t2) #=> true

Thank for your help… this is that I need…
–Andrea


#4

“R” == Ross B. removed_email_address@domain.invalid writes:

R> def ==(o)

An hash use #hash and #eql?, not #==

Guy Decoux


#5

On Dec 19, 2005, at 10:47 AM, Ross B. wrote:

end

hello"}

end
h[d = Dclz.new] = “Expected”

(Tried on both ruby 1.8.3 (2005-09-21) [i386-linux] and ruby 1.9.0
(2005-12-16) [i686-linux])


Ross B. - removed_email_address@domain.invalid

As ts already mentioned, you missed the eql? part. Me aliasing it to
== and implementing == instead is a function of my C++ (as opposed to
lisp or smalltalk(?) ) upbringing.


#6

On Mon, 19 Dec 2005 15:21:22 -0000, Logan C.
removed_email_address@domain.invalid
wrote:

alias eql? ==

t == t2 #=> true

h = {}
h[t] = “short hello”
h #=> {#<Termine:0x24a22c @lingua=“it”, @descrizione=“Hi”>=>“short
hello”}
h.has_key?(t2) #=> true

I was playing around with this, and now I’m doubly worried I have a bug,
or have missed something else. The last line in your code gives out
‘false’ for me. I was experimenting with this:

class Dclz
@str = “A string”
attr_reader :str

def ==(o)
self.str == o.str
end

def ===(o)
self.str === o.str
end

def hash
self.str.hash
end
end

case Dclz.new
when Dclz.new
puts “Works”
else
puts “doesn’t”
end # => “Works”

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] # => “Failure” huh!!!

And I cannot understand what’s happening here. Someone, please confirm
that I’m either sane or stupid?

(Tried on both ruby 1.8.3 (2005-09-21) [i386-linux] and ruby 1.9.0
(2005-12-16) [i686-linux])


#7

On Mon, 19 Dec 2005 16:04:56 -0000, Logan C.
removed_email_address@domain.invalid
wrote:

As ts already mentioned, you missed the eql? part. Me aliasing it to ==
and implementing == instead is a function of my C++ (as opposed to lisp
or smalltalk(?) ) upbringing.

Yes, I see. If I move your alias to after the definition, or just
implement eql?, it works. I assumed you were saving a reference to the
original == as ‘eql?’ (missed that it already existed), which is why I
got
‘false’ first time around. It was just that having my suspicion
apparently
confirmed kind of made me worried :wink:

Cheers :slight_smile:


#8

On Mon, 19 Dec 2005 15:56:51 -0000, ts removed_email_address@domain.invalid wrote:

“R” == Ross B. removed_email_address@domain.invalid writes:

R> def ==(o)

An hash use #hash and #eql?, not #==

Ahh, there it goes :slight_smile: Thanks kindly.