Lulu Arrays — Constructors
Introduction
If you have imported the lulu.Array
class as
local Array = require 'lulu.Array'
then, you can create new Array instances using the following methods:
Array:new(...)
or Array(...)
Creates an Array
instance by adopting an existing Lua array or by copying elements.
The function call Array(...) is a synonym for Array:new(...) .
|
Array:rep(n, value, ...)
Creates an Array
instance with a specified size and repeated initial value or repeated calls to a value function.
Array:range(start, stop, step)
Creates an array of numbers from start
to stop
with an optional step
increment. The default step size is 1.
Array:subclass(name, tbl)
Creates a subclass of Array
or a sub-subclass etc. The name
argument is optional and will be the name for the subclass. The second tbl
argument is also optional and should be a table of methods to add to the subclass.
Array:new_instance()
Returns a new empty array instance that has the same metatable as self
Array:new(...)
or Array(...)
- The no argument version returns a new empty
Array
instance. - If there is a single argument which is a Lua array then it adopts that argument and converts it to an
Array
instance by adding an appropriate metatable. - The single non-array argument version returns new one element
Array
instance with the argument as the element. - The \(n\) argument version returns an \(n\)-element
Array
instance with those \(n\) elements.
Simple Examples
local a1 = Array()
1("a1: %t", a1)
putln
local a2 = Array("whatever")
2("a2: %t", a2)
putln
local a3 = Array({1,2,3})
3("a3: %t", a3)
putln
4local a4 = Array{1,2,3}
("a4: %t", a4) putln
- 1
-
Creates the empty
Array
, - 2
-
Creates an
Array
with a single element. - 3
-
Adopts the array argument and converts it to an
Array
. - 4
-
Copies the three arguments into a new
Array
.
Output
a1: []
a2: [ "whatever" ]
a3: [ 1, 2, 3 ] a4: [ 1, 2, 3 ]
There is a subtle difference between the last two examples which we can illustrate:
- 1
-
We have adopted the Lua array
t
as theArray
a
. - 2
-
We alter the first element in
t
. - 3
-
Then look at what it does to
a
.
This outputs:
a: [ 1, 2, 3 ]1 a: [ 99, 2, 3 ]
- 1
-
As expected
a[1]
has changed — we adoptedt
soa
andt
point to the same region of memory.
Array:rep(n, value, ...)
This creates an Array
of size n
.
In the simplest case value
is just a constant:
local a = Array:rep(3, "Hallo")
("a: %s", a) putln
Outputs a: [ "Hallo", "Hallo", "Hallo" ]
.
However, value
can be a Lua function, a string lambda, a string operator, or callable object as described in lulu.callable
. It will get called for each element i
as value(i, ...)
where any extra arguments to the rep
method are forwarded to the value
function.
For example:
local a = Array:rep(5, "*", 10)
("a: %t", a) putln
Outputs a: [ 10, 20, 30, 40, 50 ]
.
That could also be written using a full Lua function definition:
local a = Array:rep(5, function(i,m) return m*i; end, 10)
("a: %t", a) putln
Outputs a: [ 10, 20, 30, 40, 50 ]
.
Array:range(start, stop, step)
This creates an Array
of numbers from start
to stop
with an optional step
increment. The default value for step
is 1. The start
number will be included in the array, the stop
may not be depending on the value for step
.
local a = Array:range(1,15,4)
("a: %t", a) putln
Outputs a: [ 1, 5, 9, 13 ]
which does not include the stop value 15
because we are using a step
size of 4
.
Array:subclass(name, tbl)
This creates a subclass of Array
or a sub-subclass etc.
The name
argument is optional. If present, it will become the name for the subclass (accessed using the Array:name
method).
The tbl
argument is also optional. If present, it can be used to pass a table of predefined methods for all instances of the subclass.
Example
1local CheckedArray = Array:subclass("CheckedArray")
2function CheckedArray:at(i)
if i > #self then
local warn = require('messages').warn
warn("Index is set to %d but it should be be at most %d", i, #self)
return nil
end
return self[i]
end
3local c = CheckedArray{1,2,3}
("c is a %s with values: %s", c:name(), c)
putln
4print(c:at(6))
- 1
-
Create
CheckedArray
as a subclass ofArray
. - 2
-
Override the
Array:at(i)
method so that it checks the index is in bounds for aCheckedArray
. - 3
-
Create an instance of
CheckedArray
with three elements. - 4
- Try to access element number 6.
Output
c is a CheckedArray with values: [ 1, 2, 3 ]
[WARNING] from 'at' (scratch.lua:10): Index is set to 6 but it should be be at most 3 nil
Note that any CheckedArray
is also an Array
but not vice-versa:
local a, c = Array{1,2,3}, CheckedArray{1,2,3}
("a is an Array: %s", Array:is_instance(a))
putln("c is an Array: %s", Array:is_instance(c))
putln("a is a CheckedArray: %s", CheckedArray:is_instance(a)) putln
Outputs:
a is an Array: true
c is an Array: true
a is a CheckedArray: false c is a CheckedArray: true