Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Set and Object equivilence

Reply
Thread Tools

Set and Object equivilence

 
 
andrew.oxenburgh@gmail.com
Guest
Posts: n/a
 
      12-11-2007
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.sh ift)" 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
 
Reply With Quote
 
 
 
 
Gary Wright
Guest
Posts: n/a
 
      12-11-2007

On Dec 11, 2007, at 10:07 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) 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 Wright

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      12-11-2007
2007/12/11, (E-Mail Removed) <(E-Mail Removed)>:
> 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.sh ift)" 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

 
Reply With Quote
 
Eric I.
Guest
Posts: n/a
 
      12-11-2007
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
!
 
Reply With Quote
 
andrew.oxenburgh@gmail.com
Guest
Posts: n/a
 
      12-11-2007
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


On Dec 11, 3:30 pm, "Eric I." <(E-Mail Removed)> wrote:
> 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 fromhttp://LearnRuby.com
> !


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Prerender and Gridview - Object reference not set to an instance ofan object. wildman@noclient.net ASP .Net 1 03-03-2008 07:51 PM
Object reference not set to an instance of an object and ceate userwizard Fendi Baba ASP .Net 0 05-13-2007 04:45 PM
Object creation - Do we really need to create a parent for a derieved object - can't the base object just point to an already created base object jon wayne C++ 9 09-22-2005 02:06 AM
msnbot and Object reference not set to an instance of an object dev@thehexx.com ASP .Net 1 11-05-2004 03:40 PM
Error !Object reference not set to an instance of an object. !!! Help Parthiv Joshi ASP .Net 2 07-02-2004 10:28 AM



Advertisments