I know that "self" in Lua is similiar to "this" in Java. "this" means current object in Java, but I know Java is object-oriented, while Lua is prototype-based. Could anyone explain why the code below has to use "self.last" instead of "self" to access the current node of the linked list? Thank you. :)
list = {}
list.__index = list
setmetatable(list, { __call = function(_, ...)
local t = setmetatable({length = 0}, list)
for _, v in ipairs{...} do t:push(v) end
return t
end })
function list:push(t)
if self.last then
self.last._next = t
t._prev = self.last
self.last = t
else
self.first = t
self.last = t
end
self.length = self.length + 1
end
You have two different kinds of objects in your program: list objects and nodes. The list object manages a chain of linked nodes and has the following fields:
listobject = {
length = 0, -- number of nodes managed by this list object
first = nil, -- reference to first node in this list; nil if list is empty
last = nil -- reference to last node in this list; nil if list is empty
}
The reference to the first node is useful for iterating and prepending to the list, while the last reference allows for efficient appending. List objects also have a metatable so that you can call methods on them:
listobject:push( {"node1"} )
Unless you do something funny, the self parameter of the push method will always be a list object, not a node.
Nodes on the other hand have references to the next and previous node in a chain:
node = {
_next = nil, -- might be nil if not in list or last node
_prev = nil, -- might be nil if not in list or first node
-- plus some data
}
So in the push method you access self.last to check whether the list is empty (you could have checked self.length as well), and if it is not, to find the last node in the current list where you can append the new node passed as argument to push. When you have done so, the last (and first) references in the list object have to be updated, obviously. The list object (self in the body of the push method) is not part of the chain of nodes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With