From: Robert Klemme Date: 2007-12-12T00:16:00+09:00 Subject: Re: Set and Object equivilence 2007/12/11, andrew.oxenburgh@gmail.com : > 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) Spelling error: this method needs to read "eql?". This is likely the cause for your issue. > 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 -------- 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 -- use.inject do |as, often| as.you_can - without end