2

I'm trying to create a simple class with a member function that would print out some member values, but I'm getting errors when I try to reference 'self':

attempt to index global 'self' (a nil value)

Here's the script I'm trying to run:

Test = {}

function Test:new()
    T = {}
    setmetatable(T, self)
    self.__index = self
    self.Name = "Test Object"
    return T
end

function Test:printName()
    print("My name is " .. self.Name) -- This causes the error
end

I've also tried self:Name but I get a similar error. What am I doing wrong here?

EDIT:

Forgot to mention that I call the printName() function from C++ code. If I call the function from Lua, it works properly.

The Test object is created in Lua and a callback function is done. The callback is called in C++ like this:

luabridge::LuaRef testObjectRef = ...; // This is populated from Lua, refers to the printName() function
testObjectRef(); // Calls the function

The callback in the script is done like this:

-- in Test:new()
self.Callback = LuaCallback(self.printName)
Helper.setCallback(self.Callback)

The callback itself works fine if I don't try to refer to self. The error comes up only when I try to do that.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
manabreak
  • 5,415
  • 7
  • 39
  • 96
  • `self.Name` *is* the correct syntax. Lemme run it. – Bartek Banachewicz Dec 03 '14 at 09:26
  • Show the code that's used to call it from C++. Are you pushing the `self` parameter on the stack? (C API doesn't have the notion of `:` call!) – Bartek Banachewicz Dec 03 '14 at 09:30
  • And now *you've forgotten to say that you're using luabridge?!!?!*. Please do read "about" section again. And I recommend using [**Sol**](https://github.com/Rapptz/sol) instead, luabridge is extremely meh in my opinion. – Bartek Banachewicz Dec 03 '14 at 09:33
  • @BartekBanachewicz My apologies, I really did think originally it was a problem in just the Lua script. However, I think the choice of luabridge is a personal preference and does not have anything to do with the problem here - suggesting to change to another library is moot as there's already a whole program built upon luabridge. – manabreak Dec 03 '14 at 09:36
  • Well, refer to your library docs about calling methods then. – Bartek Banachewicz Dec 03 '14 at 09:38
  • I have done that. As I already mention, the function call works if I don't refer `self` - the error happens only when I try to do that. As far as I've looked, there's nothing about referring `self` in the luabridge manual. – manabreak Dec 03 '14 at 09:40
  • I think you've got to live with your personal preference then. (In all seriousness, try just passing the ref as the first parameter to the call; that's *exactly* what `:` does. `self` is just an implicit first parameter if you use it.) – Bartek Banachewicz Dec 03 '14 at 09:40
  • @BartekBanachewicz There's no need to be so toxic about this. I just want to know what causes the problem and why - it's probably not related to luabridge, I suspect. – manabreak Dec 03 '14 at 09:43
  • It's related to the fact how Lua "methods" work. The fact that luabridge doesn't give you a nice way to utilize that from C++ side is kinda related, imho. Anyway, I've told you what causes the problem and why; read about how `self` works if you still don't understand it. Oh and also, if you want to bind it as a callback, you'll prolly need a lambda (or `std::bind`) to bind the self if the function takes more arguments. – Bartek Banachewicz Dec 03 '14 at 09:44

2 Answers2

1

I took your code, added:

local test = Test:new()
test:printName()

It gives me the correct output.

My name is Test Object

If you're calling it via C API, you have to remember to manually push the self argument onto the stack. Remember that:

obj:fun() ~ obj.fun(obj)
Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
1

I managed to fix the problem. I added the self as an extra argument in the listener constructor and passed it as the first parameter to the callback function.

-- in the script
self.Callback = LuaCallback(self, self.printName)
Helper.setCallback(self.Callback)
manabreak
  • 5,415
  • 7
  • 39
  • 96