Reputation: 494
I have a method that builds a Tree from a parent list pointer in lua. In particular I have this lua table
parents = {2,3,13,5,12,7,11,9,10,11,12,13,14,0}
Along with two functions:
Function 1 (creates the node):
function create_node(parent, i, created, root)
if created[i] ~= nil then
return
end
print(i)
-- print(parent)
-- Create a new node and set created[i]
local new_node = Tree()
new_node.idx = i
created[i] = new_node
-- If 'i' is root, change root pointer and return
if parent[i] == 0 then
root[1] = created[i] -- root[1] denotes root of the tree
return
end
-- If parent is not created, then create parent first
if created[parent[i]] == nil then
create_node(parent, parent[i], created, root )
end
print(i)
-- Find parent pointer
local p = created[parent[i]]
print (p)
if #p.children <=2 then
print(p.idx)
print(created[i].idx)
p.add_child(created[i])
end
end
Function 2 (creates the tree recursively): I have stopped the loop at one to test the first path from leaf to root i.e 1-2-3-13-14
function read_postorder_parent_tree(parents)
n = #parents
-- Create and array created[] to keep track
-- of created nodes, initialize all entries as None
created = {}
root = {}
for i=1, 1 do
create_node(parents, i, created, root)
end
return root[1]
end
The create_note
method uses the below Tree
class:
local Tree = torch.class('Tree')
function Tree:__init()
self.parent = nil
self.num_children = 0
self.children = {}
end
function Tree:add_child(c)
print(c)
c.parent = self
self.num_children = self.num_children + 1
self.children[self.num_children] = c
end
Everything works fine but when I call p.add_child(created[i])
the argument is nil
why? (why c
is nil
?) I have already checked that created[i]
and p
are not nil
. How can i solve this and/or why this happening?
This is the error that I get:
./Tree.lua:16: attempt to index local 'c' (a nil value)
stack traceback:
./Tree.lua:16: in function 'add_child'
main.lua:120: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:109: in function 'create_node'
main.lua:134: in function 'read_postorder_parent_tree'
main.lua:153: in function 'main'
main.lua:160: in main chunk
[C]: in function 'dofile'
...3rto/torch/install/lib/luarocks/rocks/trepl/scm-1/bin/th:150: in main chunk
[C]: at 0x00405d50
Upvotes: 2
Views: 1242
Reputation: 13177
If you define a function in an object-oriented way, you must also call it in the same way.
function Tree:add_child(c)
This declares a function in an object-oriented way using the colon operator. To help you understand what that means, it can be rewritten like this:
Tree.add_child = function(self, c)
As you can see, an implicit self
parameter is created to reflect the object the function was called on. However, you call the function via the standard way:
p.add_child(created[i])
Now you can see that what you really did was pass created[i]
as self
, not as c
, which then of course happens to be nil. The standard way to call such a function is also via the colon operator:
p:add_child(created[i])
This implicitly passes p
as self
to the actual function, and now p
will contain the actual argument.
Upvotes: 7