Lulu Arrays — Copying
Introduction
If you have imported the lulu.Array
class as
local Array = require 'lulu.Array'
then you have access to the following methods to copy Arrays
.
Array:clone()
Returns a shallow copy of self
.
Array:copy()
Returns a deep copy of self
that can include recursive and cyclical elements.
Shallow vs. Deep Copying
The Array:clone
and Array:copy
methods both start by creating a new empty Array
of the same type as self
.
A shallow clone
then inserts copies of the top-level elements from self
into that new Array
.
On the other hand, a deep copy
copies all the elements from the self
argument by recursively visiting any sub-tables, sub-sub-tables, and so on.
The methods give identical results for a simple Array where the elements are not tables.
|
Example: A Simple Array
1local a = Array{"Mary", "Sheila", "Fiona"}
local a_clone = a:clone()
local a_copy = a:copy()
("a: %t", a)
putln2("a_clone: %t", a_clone)
putln("a_copy: %t", a_copy)
putln
3a[1] = "Tom"
a_clone[2] = "Dick"
a_copy[3] = "Harry"
("After changing elements:")
putln("a: %t", a)
putln4("a_clone: %t", a_clone)
putln("a_copy: %t", a_copy) putln
- 1
-
a
is a simpleArray
with three elements. - 2
-
We expect that the output from
a:clone()
anda:copy()
to be the same. - 3
- We alter one element in each of the three Arrays.
- 4
-
We check to see if the three
Arrays
are completely independent.
Output:
a: [ "Mary", "Sheila", "Fiona" ]
a_clone: [ "Mary", "Sheila", "Fiona" ]1
a_copy: [ "Mary", "Sheila", "Fiona" ]
After changing elements:
a: [ "Tom", "Sheila", "Fiona" ]
a_clone: [ "Mary", "Dick", "Fiona" ]2 a_copy: [ "Mary", "Sheila", "Harry" ]
- 1
-
The three
Arrays
are identical. - 2
-
The three
Arrays
are independent.
Example: An Array with table elements
local p1, p2 = {name = 'John', age = 25}, {name = 'Mary', age = 23}
1local a = Array(p1, p2)
local a_clone = a:clone()
local a_copy = a:copy()
("a: %t", a)
putln("a_clone: %t", a_clone)
putln2("a_copy: %t", a_copy)
putln
a[1].name = 'Tom'
a_clone[2].name = 'Fiona'
("After changing elements in `a` and `a_clone`:")
putln("a: %t", a)
putln("a_clone: %t", a_clone)
putln3("a_copy: %t", a_copy)
putln
a_copy[1].name = 'Goofy'
("After changing elements in `a_copy`:")
putln("a: %t", a)
putln("a_clone: %t", a_clone)
putln4("a_copy: %t", a_copy) putln
- 1
-
In this case
a
is anArray
whose elements are themselves tables. - 2
- We expect to see the same output from all of these print statements.
- 3
- But what do you expect to happen here?
- 4
- And here?
Output:
1
a: [ { age = 25, name = "John" }, { age = 23, name = "Mary" } ]
a_clone: [ { age = 25, name = "John" }, { age = 23, name = "Mary" } ]
a_copy: [ { age = 25, name = "John" }, { age = 23, name = "Mary" } ]
After changing elements in `a` and `a_clone`:2
a: [ { age = 25, name = "Tom" }, { age = 23, name = "Fiona" } ]
a_clone: [ { age = 25, name = "Tom" }, { age = 23, name = "Fiona" } ]3
a_copy: [ { age = 25, name = "John" }, { age = 23, name = "Mary" } ]
After changing elements in `a_copy`:4
a: [ { age = 25, name = "Tom" }, { age = 23, name = "Fiona" } ]
a_clone: [ { age = 25, name = "Tom" }, { age = 23, name = "Fiona" } ] a_copy: [ { age = 25, name = "Goofy" }, { age = 23, name = "Mary" } ]
- 1
- The three arrays look identical.
- 2
-
This shows that the elements in
a_clone
are really just references to the same blocks of memory used for the elements ofa
. - 3
-
The
a_copy
object is completely untouched by those changes as it is a deep copy ofa
. - 4
-
This reinforces the fact that
a_copy
is independent froma
and it mirrora_clone
.