Submitted by coreywangler (Wed Jan 21 04:01:44 UTC 2004)
The ideas of equivalency and identity are not represented consistently by the current method names. This proposal deals with this issue by having Object#equal? behave as an equivalency test, and introducing Object#identical? as an identity test.
Current meaning of Object#equal? is not consitent with the ideas of equivalence and identity.
Add Object#identical? to check for identical objects (i.e. the current behaviour of Object#equal?).
Change behaviour of the Object#equal? method to check for equivalency of value and class. The method can then be thought of as to mean "more equivalent" than Object#eql?, and would be useful for testing the equivalency of duplicates and clones.
The following code is an example of what is proposed:
class Object def identical?( other ) self.id == other.id end def equal?( other ) (self.class.id == other.class.id) and self.eql?(other) end end @test_fmt = "%12s : %7s %8s %9s %10s\n" def test_head printf @test_fmt, "func", "==", "eql?", "equal?", "identical?" end def test(x_name, y_name, x, y) printf @test_fmt, x_name+'.func('+y_name+')', x==y, x.eql?(y), x.equal?(y), x.identical?(y) end z = Array.new.concat([1,2,3]) a = z b = a.dup c = a.dup; c[0]=1.0 class Array2 < Array end b2 = Array2.new.concat([1,2,3]) c2 = b2.dup; c2[0]=1.0 test_head; \ test('a','z',a,z); \ test('b','z',b,z); \ test('b2','z',b2,z); \ test('c','z',c,z); \ test('c2','z',c2,z) # # func : == eql? equal? identical? # a.func(z) : true true true true # b.func(z) : true true true false # b2.func(z) : true true false false # c.func(z) : true false false false # c2.func(z) : true false false false #
Changing Object#equal? to have behaviour of an equivalency test avoids confusion, because its meaning is then consistent with the other equivalency methods (eql?, ==, ===).
By making the Object#equal? method test for equivalency of value and class, it becomes a useful method for testing equivalence of dup'ed or clone'ed objects.
Using Object#identical? to check if objects are identical (same object id) makes more sense because the method does what you would expect it to do.
Have Object#identical? do what Object#equal? currently does.
Also, change behaviour of the Object#equal? method.
The following code is an example of what is required.
class Object def identical?( other ) self.id == other.id end def equal?( other ) (self.class.id == other.class.id) and self.eql?(other) end end
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
Why should we introduce incompatibility by changing basic method behavior, when virtually no one has had troubles about these names? "identity?" may be better than "equal?", but I'm not sure it's good enough to change.
-matz.
Certainly this is something that would have to be phased-in slowly. But I agree, Ruby is a bit too numerous with concepts (and thus methods) of equality. Using identity to help contrast the extremity of absolute sameness would, I believe, be helpful, especially to the nuby (and indeed the nuby in all of us b/c we all sometimes forget).
-T.
IMHO, being equivalent (or "equal") is a totally different concept to being identical. When learning ruby (well, I still have a long way to go!) this area required more thinking than necessary due to the mixing of these two concepts.
Deprecating #equal? and replacing with #identical? would remove this issue.
I suggested a new behaviour for #equal? that is in line with the current equivalency methods. Maybe deprecating #equal? without replacing it with a new behaviour would address your concern regarding incompatability?
Yes, I am being picky. I really admire the clarity that the ruby language has, and I'm just suggesting an (albeit small) improvement to that clarity. Yes, developers can learn almost anything that is in a language... but the aim is to have less to learn, isn't it?
Note that I have made a small change to the proposal. #equal? implementation now uses #eql? instead of == in the expression, making it more in line with the "more equal" theme.
-corey.
Here I'm going to start arguing with myself... ;)
One line of thinking could be that being identical is another shade of being "more equal". Also, introducing another method name in this area is another thing to remember in itself.
As for clones/duplicates, is it useful to have #equal? with the suggested behaviour?
-corey.I don't think we should change equal?. But I agree that it appears someway misleading. I think object.same?(other) could be cool :)
I was thinking that "Object#identical?" is more in line with "Object#id" (identity/identifier), but "Object#same?" would work too (less typing may be a bonus ;-).
-corey.
I can't help thinking that a.id == b.id isn't so bad....
David Black
Yep, so maybe don't have an #identical? or #same? method at all. What would you suggest happen to #equal?
-corey.
I'd choose "leave it as is". They are "equal" in a sense of identity.
-- matz
Yep, cool. Thanks everyone for your input. Withdrawing this RCR.
-corey.