I broke it

I have a stack of cards that I want to select by touch. This code used to work. I changed something in Main and now it doesn’t work, but I cannot for the life of me figure out what I did to it.

function Stack:selectCards(n1)
    print(n1)
    if n1<1 then
        self.selected=-1
    elseif n1>#self.cards then
        self.selected=#self.cards
    else
        n1 = #self.cards+1-n1
        self.selected=n1
    end
end

The problem is when calling the function, n1 receives a nil value. The print statement proves it then the condition fails.

The only thing I believe I did between working and not working was remove the test line in Main from setup() to a function dependent on the touch handler. When it broke the code, I moved it back to setup. Neither works now. I thought maybe I created a variable name clash, so I changed it from n to n1 and it still doesn’t work.

I know it has to be something stupid and I’m going to be embarrassed when I realize how simple it was.

The line in Main is: stacks[stackFrom].selectCards(1) and again, it is calling the function, just the parameter is nil.

Any ideas?

(Updated) You are calling the function in Main with a fullstop and not with a colon:

stacks[stackFrom]:selectCards(1)

(Edit #2) Your function is the equivalent of:

function Stack.selectCards(self, n1)

When you call it as stacks[stackFrom].selectCards(1) that is the same as calling it as:

stacks[stackFrom].selectCards(1, nil)

so n1 is nil.

Oh you’re a genius.

I’m used to Java. I don’t really get why Lua needs : instead of dots.

Thanks. I knew it was stupid.

The : is syntactic sugar (i.e. a shortcut for a commonly used pattern) for passing a table or userdata as the first argument to a function that is assigned to that table/userdata, effectively making the function a “member” function. There are 2 places where the colon has this meaning. One is when defining the function, and the other is when calling it.

For example, when writing a function intended to be a “member” function, you could forego the colon syntax and define your function the long way, like the following examples:

function someTable.someFunction(self)
     doSomething(self)
end

or

someTable.someFunction = function(self)
     doSomething(self)
end

Since this function is intended to be a “member” function for “someTable”, you could use the colon syntax to write it like this instead:

function someTable:someFunction()
     doSomething(self)
end

Note that when you define a function using the colon, “self” is implicitly defined as the first argument to that function.

When calling a function that belongs to a table using the colon syntax, we are telling Lua to pass that table as the implicit “self” argument to that function. So:

someTable:someFunction()

is really just a shortcut for

someTable.someFunction(someTable)

The Programming In Lua book goes into some detail about how object orientation is achieved in Lua, and does a great job of explaining the motivation for the : syntax (http://www.lua.org/pil/16.html#ObjectSec).

Be aware though that the online version of the book references Lua 5.0, while Codea uses Lua 5.1. Even so, that chapter is relevant and might explain this better than I am able to.