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
-matz.
-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?
== -- pretty much the same value 1 == 1.0 gives true eql? -- the same value 1.eql?(1.0) gives false equal? -- same value and same class (a clone or duplicate object) identical? -- is identical, i.e. the same object
-corey.
-corey.
I can't help thinking that a.id == b.id isn't so bad....
David Black
-corey.
I'd choose "leave it as is". They are "equal" in a sense of identity.
-- matz
-corey.
-matz.
-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?
== -- pretty much the same value 1 == 1.0 gives true eql? -- the same value 1.eql?(1.0) gives false equal? -- same value and same class (a clone or duplicate object) identical? -- is identical, i.e. the same object
-corey.
-corey.
I can't help thinking that a.id == b.id isn't so bad....
David Black
-corey.
I'd choose "leave it as is". They are "equal" in a sense of identity.
-- matz
-corey.
Back to RCRchive.
RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog