Alberto Merciai
Alberto Merciai

Reputation: 494

why passing an argument to lua class method get nill

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

Answers (1)

IS4
IS4

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

Related Questions