feat: add Object.same static method for reliable built-in equality

Introduce a new static method `Object.same(obj1, obj2)` that exposes the VM's
built-in equality semantics (`wrenValuesEqual`) directly, bypassing any
user-defined `==` overrides. This required creating a dedicated metaclass for
Object (subclass of Class) to host the static method without polluting every
class with a `same` method. The implementation wires up a new `Object metaclass`
in the core initialization sequence, adjusts the class hierarchy setup order,
and adds comprehensive tests covering value types, identity comparison, and
verification that `Object.same` ignores custom `==` operators.
This commit is contained in:
Bob Nystrom
2015-05-01 14:55:28 +00:00
parent cbfbb3a4cd
commit 332f570a1a
6 changed files with 116 additions and 31 deletions
+5 -1
View File
@@ -5,5 +5,9 @@ IO.print(Foo.type.name) // expect: Foo metaclass
// Make sure the built-in classes have proper names too.
IO.print(Object.name) // expect: Object
IO.print(Class.name) // expect: Class
IO.print(Bool.name) // expect: Bool
IO.print(Class.name) // expect: Class
// And metaclass names.
IO.print(Object.type.name) // expect: Object metaclass
IO.print(Bool.type.name) // expect: Bool metaclass
+1 -1
View File
@@ -3,7 +3,7 @@ class Foo {}
// A class is a class.
IO.print(Foo is Class) // expect: true
// It's metatype is also a class.
// Its metatype is also a class.
IO.print(Foo.type is Class) // expect: true
// The metatype's metatype is Class.
+40
View File
@@ -0,0 +1,40 @@
// Value types compare by value.
IO.print(Object.same(true, true)) // expect: true
IO.print(Object.same(true, false)) // expect: false
IO.print(Object.same(null, null)) // expect: true
IO.print(Object.same(1 + 2, 2 + 1)) // expect: true
IO.print(Object.same(1 + 2, 2 + 2)) // expect: false
IO.print(Object.same(1..2, 1..2)) // expect: true
IO.print(Object.same(1..2, 1..3)) // expect: false
IO.print(Object.same("ab", "a" + "b")) // expect: true
IO.print(Object.same("ab", "a" + "c")) // expect: false
// Different types are never the same.
IO.print(Object.same(null, false)) // expect: false
IO.print(Object.same(true, 2)) // expect: false
IO.print(Object.same(1..2, 2)) // expect: false
IO.print(Object.same("1", 1)) // expect: false
// Classes compare by identity.
IO.print(Object.same(Bool, Num)) // expect: false
IO.print(Object.same(Bool, Bool)) // expect: true
// Other types compare by identity.
class Foo {}
var foo = new Foo
IO.print(Object.same(foo, foo)) // expect: true
IO.print(Object.same(foo, new Foo)) // expect: false
// Ignores == operators.
class Bar {
==(other) { true }
}
var bar = new Bar
IO.print(Object.same(bar, bar)) // expect: true
IO.print(Object.same(bar, new Bar)) // expect: false
+13
View File
@@ -0,0 +1,13 @@
class Foo {}
// Object's class is a class.
IO.print(Object is Class) // expect: true
// Its metatype is also a class.
IO.print(Object.type is Class) // expect: true
// The metatype's metatype is Class.
IO.print(Object.type.type == Class) // expect: true
// Object has a distinct metaclass.
IO.print(Object.type.name) // expect: Object metaclass