Thank you Joel for the answer.
This is what I ended up with
···
On Fri, Jun 18, 2004 at 10:15:44AM +0900, Joel VanderWerf wrote:
Zakaria wrote:
>Hi,
>
>Currently I got many simple class which is just a simple record-like.
>An example
>-----------------------------------
>class LoopTag # :nodoc:
> attr_reader :param
> attr_reader :contents
>
> def initialize(param)
> @param, @contents = param,
> end
>
> def ==(other)
> return false unless other.class == self.class
> return other.param == @param && other.contents == @contents
> end
>end
>------------------------------------
>and I got a couple more class like this.
>Is there a way to make a generic #== or some Module that I can include ?
One way I've done it is this:
module ContentEquality
def hash
content.hash
end
def eql?(other)
content.eql? other.content
end
def ==(other)
# self.class == other.class and # optional
content == other.content
end
end
Just include the module and define a content method that returns
something like and array of objects that are significant for comparison
purposes:
class LoopTag
include ContentEquality
def content
[@param, @contents]
end
end
Another way might be to iterate over a list of instance variables (or
all of 'em, if that's what you want).
----------------------------------------------------------------------------
module AttrsEquality
def ==(other)
self.class === other && attrs == other.attrs
end
def attrs
res = {}
instance_variables.each {|n| res[n.intern] = instance_variable_get(n) }
res
end
end
----------------------------------------------------------------------------
with unit-test
----------------------------------------------------------------------------
class TC_AttrsEquality < Test::Unit::TestCase
class T1
include AttrsEquality
def initialize(a, b, c, d)
@a, @b, @d, @c = a, b, d, c
end
end
def test_attrs
t = T1.new(1, 'ab', ['some', 4], {'x' => 1, 3 => 'y'})
x = {:@a => 1, :@b => 'ab', :@c => ['some', 4],
:@d => {'x' => 1, 3 => 'y'}}
assert_equal(x, t.attrs)
end
def test_equal
t1 = T1.new(1, 'ab', ['some', 4], {'x' => 1, 3 => 'y'})
t2 = T1.new(1, 'ab', ['some', 4], {'x' => 1, 3 => 'y'})
assert(t1 == t2, 'equal')
end
end
----------------------------------------------------------------------------
I remove the eql? and hash method because
1) I don't need it
2) It doesn't work if the class has hash attribute because
{'a' => 1}.hash != {'a' => 1}.hash
3) I'm not really understand the functionality to test it
Could someone enlighten me why Hash#hash doesn't result the same
and where .hash and .eql? used ?
PS: Is there any place where I could post this snippet,
so others could use it?
Wassallam,
-- Zakaria
z4k4ri4@bigfoot.com Yahoo!: z4k4ri4
http://zakaria.is-a-geek.org
http://pemula.linux.or.id