Duplicity in Set


#1

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


#2

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


#3

Thanks Daniel, I omitted the eql?. Now it works.
Radek