Using self keyword in a class in Lua

I know that "me" in Lua is like "this" in Java. "this" means the current object in Java, but I know Java is object-oriented and Lua is prototype. Can anyone explain why the below code should use "self.last" instead of "self" to access the current node of the linked list? Thank.:)

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

      

+3


source to share


2 answers


There are two different types of objects in your program: list of objects and nodes. The list object manages a chain of related 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 link to the first node is useful for iterating and adding to the list, and the link last

allows you to add efficiently. List objects also have a meta tag so you can call them with methods:

listobject:push( {"node1"} )

      



Unless you do something funny, the self

method parameter push

will always be a list object, not a node.

Nodes, on the other hand, have links to the next and previous node in the 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 method, push

you access to self.last

check if it is empty (you might as well check self.length

), and if not, find the last node in the current list to which you can add a new node passed as an argument push

. When you've done that, the links last

(s first

) in the list object should be updated, obviously. The list object ( self

in the body of the method push

) is not part of the chain of nodes.

+2


source


self

used to access the previous argument being called into the list. For example, if you called list({"Hello"}, {"world"}, {"my"}, {"name"}, {"is"})

, you list:push

would get the name five . One call for each argument.

If no last (this self.last

) argument is specified (this refers to the first argument), it will set {"Hello"}

to t = {"Hello"}; t.first = t; t.last = t;

(self referring tables).



If it is second and onwards, it tells the previous table ( {"Hello"}

) that the next table is {"my"}

, reports {"my"}

what the previous table is, and also sets the current table in the entire "list" as the last one. Be aware that this list:push(t)

is called multiple times. This means that self.last is called many times, but after the list has been created, only one table (the last argument) is in self.last

, and each table has an entry for the next or previous table in the list.

0


source







All Articles