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}
2putln("a: %t", a)
putln("b: %t", b)
3putln("a:eq(b) returns: %s", a:eq(b))
4putln("rawequal(a,b) returns: %s", rawequal(a,b))
5putln("a == b returns: %s", a == b)- 1
-
Set up two simple
Arrayinstances with identical content. - 2
-
We use
putlnfromlulu.scribefor formatted output. - 3
-
The
eqmethod checks thatais the same type and has the same content asb. - 4
-
By default, a statement like
a == buses Lua’srawequalcall that looks the memory addresses foraandb. - 5
-
However, we overrode
a == bso that it instead usesa:eq(b)under the covers.
Output
a: [ 1, 2, 3 ]
b: [ 1, 2, 3 ]
1a:eq(b) returns: true
2rawequal(a,b) returns: false
3a == b returns: true- 1
-
Here
aandbhave identical elements soeqreturnstrue. - 2
-
The two arrays occupy separate memory regions so
rawequal(a,b)returnfalse. - 3
-
Nevertheless,
a == breturns the intuitively correcttrueanswer.
Another Example
1local a, b = Array{{1,2,3}, {4,5,6}}, Array{{1,2,3}, {4,5,6}}
putln("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)- 1
-
Once again,
aandbhave 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 ] ]
1a:eq(b) returns: true
2rawequal(a,b) returns: false
3a == b returns: true- 1
- The deep check for content equality passes as we’d expect.
- 2
-
aandboccupy separate memory regions so this check for address equality fails. - 3
-
Once again,
a == breturns the intuitively correcttrueanswer.
An Example with a Cycle
local a, b = Array{ 1,2,3} , Array{ 1,2,3 }
1a[4] = a
b[4] = b
putln("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)- 1
-
We add a fourth elements to the
Arraysthat is a (spurious) self-reference.
Output
a: <table> = [ 1, 2, 3, <table> ]
b: <table> = [ 1, 2, 3, <table> ]
1a:eq(b) returns: true
2rawequal(a,b) returns: false
3a == b returns: true- 1
-
The self-references are handled without any stack overflow and the
eqmethod sees that the content ofaandbmatches. - 2
-
aandboccupy separate memory regions so this check for address equality fails. - 3
-
Once again,
a == breturns the intuitively correcttrueanswer as we’ve overridden the default Lua behaviour.