Set and Object equivilence

Hi,

I’ve just started with Ruby from Java, and am having trouble getting a
set to recognise equivalence between objects. Basically it is adding
multiple equal objects to the set.

I have created a class and overridden all of the operators <=> , ==,
<, >, eqls?, equals?, hash to indicate that it should use an internal
variable to compare.

Please find enclosed a unit test, the object, and the output from the
test. Cool language BTW. Really enjoying it up until this moment. I’m
probably missing some subtlety of the language.

Any help greatly appreciated.
-------- source starts --------

require “test/unit”
require “set”

class JunkTest < Test::Unit::TestCase
def test_arraysMuckingAroundWith
a = Thingy.new(1)
b = Thingy.new(2)
c = Thingy.new(1)
d=Set.new
d << a
d << b
d << c
puts “output set, with duplicates - the first 2 object should
be equivilent” + d.sort.to_s
end
end

class Thingy

attr_accessor :value

def <=> (thing)
    self.value <=> thing.value
end

def == (thing)
    self.value == thing.value
end

def > (thing)
    self.value > thing.value
end

def < (thing)
    self.value < thing.value
end

def eqls? (thing)
    self.value.eqls?(thing.value)
end

def equals? (thing)
    self.value.equals?(thing.value)
end

def initialize(val)
    @value = val
end

def hash
    puts "hash " + @value.hash.to_s
    @value.hash
end

def to_s
    value.to_s + ", "
end

end
-------- source ends --------

-------- output starts --------

C:\dev\ruby\bin\ruby.exe -e
“STDOUT.sync=true;STDERR.sync=true;load($0=ARGV.shift)” C:/projects/
SearchJars/test/JunkTest.rb --name test_arraysMuckingAroundWith
Loaded suite C:/projects/SearchJars/test/JunkTest
Started
hash 3
hash 5
hash 3
output set, with duplicates - 1, 1, 2,
.
Finished in 0.0 seconds.

1 tests, 0 assertions, 0 failures, 0 errors

Process finished with exit code 0

-------- output ends --------

Regards

Andrew Oxenburgh

2007/12/11, [email protected] [email protected]:

Please find enclosed a unit test, the object, and the output from the
def test_arraysMuckingAroundWith
end
self.value == thing.value
def eqls? (thing)
Spelling error: this method needs to read “eql?”. This is likely the
cause for your issue.

output set, with duplicates - 1, 1, 2,
.
Finished in 0.0 seconds.

1 tests, 0 assertions, 0 failures, 0 errors

Process finished with exit code 0

-------- output ends --------

It seems the output does not stem from the code you present because
the print statement looks different.

Few remarks: you can make your life easier by including Comparable and
only implementing <=>; then <, <=, > and >= will be automatically be
derived.

You can make your life even simpler by just doing

Thing = Struct.new :value

Cheers

robert

On Dec 11, 2007, at 10:07 AM, [email protected] wrote:

def eqls? (thing)
    self.value.eqls?(thing.value)
end

You’ve got the name wrong, it should be eql?(thing).

def equals? (thing)
    self.value.equals?(thing.value)
end

You probably mean equal?(thing), but you should never redefine
equal?(x) anyway as it always assumed to be an object identity
test.

Gary W.

Hi Andrew,

First, change your .eqls? method to .eql? and that will fix your code.

Also, you should look into the Comparable mix-in module. Basically,
if you define the spaceship operator (<=>) and include Comparable in
your class, it will define it will define all the relational operators
(==, <, <=, >, >=) and between? for you. Plus, != is internally
implemented as the boolean negation of ==, so you get that also.

For Set member equality, two methods are used – eql? and hash.

Eric

====

On-site, hands-on Ruby training is available from http://LearnRuby.com
!

Thanks. Bit embarrassed with a simple spelling error. I looked at it
for ages, and tried all sorts of permutations and combinations of set
c’strs and adding methods!

I’ll check out the Comparable mixin as well.

Regards

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs