Page 1 of 1

self (A nil value)

Posted: Sun Sep 21, 2014 1:52 am
by AlgorithmEnigma
Ok so here is the code

Code: Select all

function love.update(dt)
if gui.Button({text = "Test",pos = {100, 100}}) then
self:remove()
end
end
and the error

Code: Select all

main.lua:26: Attempt to index global self(a nil value)
why does self not work?

Re: self (A nil value)

Posted: Sun Sep 21, 2014 4:06 am
by ivan
'self' can be accessed when your are inside a function like this:

Code: Select all

obj = {}
obj.remove = function(self)
  assert(self == obj)
end
or this:

Code: Select all

obj = {}
function obj:remove()
  assert(self == obj)
end
In your case, you are trying to access "self" from the global function "love.update"

Also, there are two ways to pass the 'self' reference, explicit:

Code: Select all

obj.remove(obj)
Implicit:

Code: Select all

obj:remove()

Re: self (A nil value)

Posted: Sun Sep 21, 2014 8:22 am
by Ortimh
self can't be accessed when you're not inside a method. So basically, argument self at ivan's obj.remove function not the same as obj until you pass the function using obj as the argument to make self equals to obj like ivan said. I mean you can't accessed self to return as obj object.

Code: Select all

function obj:remove()
    self = nil
end
not the same as

Code: Select all

function obj.remove(self)
    self = nil
end
At those functions, the first one make obj as nil and the second one make self as nil not the obj.

Code: Select all

local tabletest = {}

obj.remove(tabletest)
So the obj.remove makes tabletest as nil not the obj itself.

Re: self (A nil value)

Posted: Sun Sep 21, 2014 9:20 am
by Robin
In this case, I think you want something like:

Code: Select all

function love.update(dt)
     if not buttonClicked then
        if gui.Button({text = "Test",pos = {100, 100}}) then
            buttonClicked = true
        end
    end
end

Re: self (A nil value)

Posted: Wed Sep 24, 2014 2:37 am
by hardcrawler
To add a little (I hope) more to the explanations...

The behavior of "self" in Lua is not quite the same the behavior of self/this in say C++, Java, PHP etc. In those languages, the self/this is inherently available on any methods that are defined within the classes. It is essentially invalid to invoke the methods in a way in which self/this is not available. Unless you explicitly define a method as static, you can be assured that self/this is available.

In Lua, the situation is much murkier. "self" really only exists by convention. The ":" method invocation syntax is actually kind of a "trick," (something people like to call syntactic sugar). Honestly, I am not a big fan of this aspect of the language.

Here is a code snippet that demonstrates this point:

Code: Select all

local foo = {
        x = 5,
}

function foo.bar( self )
        if self then
                print("In bar, self exists and self.x is " .. tostring(self.x))
        else
                print("In bar, self is nil")
        end
end

function foo:czar()
        if self then
                print("In czar, self exists and self.x is " .. tostring(self.x))
        else
                print("In czar, self is nil")
        end
end

foo.bar()
foo:bar()
foo.bar(foo)

foo.czar()
foo:czar()
foo.czar(foo)
Note that the function "bar" is defined somewhat oddly. The reality is that when you define a function in Lua using the ":" operator, it's really being defined as you see "bar" defined. Thus, the definition of "czar" is equivalent to the definition of "bar." The funky thing, though, is that it's actually the invocation of the function that is key. If you don't invoke the function with the ":" operator (or explicitly pass the table you're using), then the method does not have access to "self"

This may be somewhat confusing, but if you pay close attention to this code example, it should be clear why your code is not doing what you want it to.