Robert Klemme
12/11/2007 3:16:00 PM
2007/12/11, andrew.oxenburgh@gmail.com <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