TheYAML change the id of Object

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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

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

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.

--
Posted via http://www.ruby-forum.com/\.

Logan Capaldo 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

--
Posted via http://www.ruby-forum.com/\.

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])

···

On Mon, 19 Dec 2005 15:21:22 -0000, Logan Capaldo <logancapaldo@gmail.com> wrote:

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

I'm using an hash object and i use a Termine Object for the key and, for
now, a String for the value.

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

--
Ross Bamford - rosco@roscopeco.remove.co.uk

   def ==(o)

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

Guy Decoux

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.

···

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

On Mon, 19 Dec 2005 15:21:22 -0000, Logan Capaldo > <logancapaldo@gmail.com> wrote:

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

I'm using an hash object and i use a Termine Object for the key and, for
now, a String for the value.

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

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])

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Ahh, there it goes :slight_smile: Thanks kindly.

···

On Mon, 19 Dec 2005 15:56:51 -0000, ts <decoux@moulon.inra.fr> wrote:

> def ==(o)

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

--
Ross Bamford - rosco@roscopeco.remove.co.uk

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:

···

On Mon, 19 Dec 2005 16:04:56 -0000, Logan Capaldo <logancapaldo@gmail.com> 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.

--
Ross Bamford - rosco@roscopeco.remove.co.uk