Lulu Arrays — Equality Checking
Introduction
If you have imported the lulu.Array
class as
local Array = require 'lulu.Array'
then you can check for equality between Array
instances using the Array:eq
method:
Array:eq(rhs, check_mt)
Returns true
if self
& rhs
are both Arrays
of the same type with identical content. This method does a deep comparison between Arrays
with table elements. It can handle table elements with recursive and cyclical references.
The check_mt
argument is optional and defaults to true
.
If you set check_mt
to false
then the method will only check the content of the arrays and not the metatables.
The class also points the standard Lua comparison operators at this method so that a == b and a ~= b will call a:eq(b) under the covers.
|
Example
1local a, b = Array{1,2,3}, Array{1,2,3}
2("a: %t", a)
putln("b: %t", b)
putln3("a:eq(b) returns: %s", a:eq(b))
putln4("rawequal(a,b) returns: %s", rawequal(a,b))
putln5("a == b returns: %s", a == b) putln
- 1
-
Set up two simple
Array
instances with identical content. - 2
-
We use
putln
fromlulu.scribe
for formatted output. - 3
-
The
eq
method checks thata
is the same type and has the same content asb
. - 4
-
By default, a statement like
a == b
uses Lua’srawequal
call that looks the memory addresses fora
andb
. - 5
-
However, we overrode
a == b
so that it instead usesa:eq(b)
under the covers.
Output
a: [ 1, 2, 3 ]
b: [ 1, 2, 3 ]1
a:eq(b) returns: true2
rawequal(a,b) returns: false3 a == b returns: true
- 1
-
Here
a
andb
have identical elements soeq
returnstrue
. - 2
-
The two arrays occupy separate memory regions so
rawequal(a,b)
returnfalse
. - 3
-
Nevertheless,
a == b
returns the intuitively correcttrue
answer.
Another Example
1local a, b = Array{{1,2,3}, {4,5,6}}, Array{{1,2,3}, {4,5,6}}
("a: %t", a)
putln("b: %t", b)
putln("a:eq(b) returns: %s", a:eq(b))
putln("rawequal(a,b) returns: %s", rawequal(a,b))
putln("a == b returns: %s", a == b) putln
- 1
-
Once again,
a
andb
have identical content. However, in this case, the array elements are themselves Lua tables.
Output
a: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
b: [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]1
a:eq(b) returns: true2
rawequal(a,b) returns: false3 a == b returns: true
- 1
- The deep check for content equality passes as we’d expect.
- 2
-
a
andb
occupy separate memory regions so this check for address equality fails. - 3
-
Once again,
a == b
returns the intuitively correcttrue
answer.
An Example with a Cycle
local a, b = Array{ 1,2,3} , Array{ 1,2,3 }
1a[4] = a
b[4] = b
("a: %t", a)
putln("b: %t", b)
putln("a:eq(b) returns: %s", a:eq(b))
putln("rawequal(a,b) returns: %s", rawequal(a,b))
putln("a == b returns: %s", a == b) putln
- 1
-
We add a fourth elements to the
Arrays
that is a (spurious) self-reference.
Output
a: <table> = [ 1, 2, 3, <table> ]
b: <table> = [ 1, 2, 3, <table> ]1
a:eq(b) returns: true2
rawequal(a,b) returns: false3 a == b returns: true
- 1
-
The self-references are handled without any stack overflow and the
eq
method sees that the content ofa
andb
matches. - 2
-
a
andb
occupy separate memory regions so this check for address equality fails. - 3
-
Once again,
a == b
returns the intuitively correcttrue
answer as we’ve overridden the default Lua behaviour.