Forum: Ruby Duplicity in Set

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
79395a0456810dd3a8c1f95c588cce03?d=identicon&s=25 Radek Skokan (Guest)
on 2006-04-11 12:30
(Received via mailing list)
Hello,

I have a Set which should contains elements of my object Component. The
component class implements method hash. I'm gathering data, createing
Componets from them and storing it into the Set. It's a Set just to
prevent
duplicates. But finally the Set contains duplicate elemets -- with the
same
hash value.

Few snippets from the code:

$components = Set.new        # declaration of the Set variable
.... then some addings to $components ...
$components.each {|c| puts(c.name + ', class:' + c.class.name + ',
hash:' +
c.hash.to_s)}

And it prints:

OR-copm2.2, class:Component, hash:304328379
OR-copm2.2, class:Component, hash:304328379

The Component class is defined in this way:

Class Component
    attr_reader :attributes, :name, :subcomponents
    attr_writer :attributes # array of Attribute objects

    def assembly?
        @subcomponents.length != 0
    end

    def object_id
        @name.object_id
    end

    def hash
        @name.hash
    end

    def initialize(name)
        @name = name
        @attributes = Hash.new
        @subcomponents = Array.new
    end
end

What am I doing wrong?

Thanks,
Radek
9358cc96c46055cd68d4a76a9aefe026?d=identicon&s=25 Daniel Harple (Guest)
on 2006-04-11 13:10
(Received via mailing list)
On Apr 11, 2006, at 12:28 PM, Radek Skokan wrote:

> I have a Set which should contains elements of my object Component.
> The
> component class implements method hash. I'm gathering data, createing
> Componets from them and storing it into the Set. It's a Set just to
> prevent
> duplicates. But finally the Set contains duplicate elemets -- with
> the same
> hash value.

You must implement #eql? and #hash --

require 'set'

class Component
   attr_accessor :attributes
   attr_reader :name, :subcomponents
   def initialize(name)
     @name = name
     @attributes = {}
     @subcomponents = []
   end
   def inspect() %{<%s hash=%#x @name=%s>} % [self.class.name,
self.hash, @name.inspect] end
   def eql?(other) @name.eql?(other.name) end
   def hash() @name.hash end
end

components = Set.new
components << Component.new("foo")
components << Component.new("bar")
components << Component.new("foo")
components.each { |c| puts c.inspect }

-- Daniel
79395a0456810dd3a8c1f95c588cce03?d=identicon&s=25 Radek Skokan (Guest)
on 2006-04-11 13:41
(Received via mailing list)
Thanks Daniel, I omitted the eql?. Now it works.
Radek
This topic is locked and can not be replied to.