1

Trying to get my feet wet with LUA and Love2D, and I am having an issue with object instantiation / access in Lua.

Source with the bug can be found here: https://bitbucket.org/dannsee/love_scrollingshooter

I am In my main, I create an object, Enemies

enemies = Enemies:new()

and inside of the enemies object, i create an object to hold peristant values, which I am calling Timers.

timers = Timers:new()

So the enemies 'constructor' method looks (basically) like this

Enemies = {} -- so that Enemies will not be nil when new() is called
timers = {} -- so that timers will be accessible in the class scope

function Enemies:new(enemies)
  enemies = enemies or {}
  timers = Timers:new()
  setmetatable(enemies, self)
  self.__index = self
  return enemies
end

while the Timers being created are looking as such

Timers = {} -- so that Timers will not be nil when new() is called

function Timers:new(timers)
    timers = timers or {
      miniBombTimerMax = 0.2,
      miniBombTimer = minibombTimerMax
    } 
    setmetatable(timers, self)
    self.__index = self
    return timers
end

But when I try to refrence one of the timers ( from inside the enemies object) , I am getting a nil value exception.

timers.miniBombTimer -- Produces nil exception

It seems to me that this should both 1. be in scope, since it is an object created inside this class, and is instantiated locally as timers = {} before it is assigned a value, and 2. not nil becuase it is being given a value in the 'constructor'. But it seems there is more going on here that I am not grasping.

I am new to Lua, which may be obvious at this point, but from what I have read about variable scope it seems that this should be valid. I don't understand why the timers are not being created with values.

2
  • Read through lua-users.org/wiki/ObjectOrientationTutorial? You didn't show the part of the code with the problem, but presumably you're not using self? Commented Aug 21, 2017 at 16:24
  • Your constructors are also not using self. I'm assuming you want timers to be a member of the Enemies class, but maybe not? Perhaps you can share a minimal example of how you intend to use this class. Commented Aug 21, 2017 at 16:36

1 Answer 1

2

Careful with your globals! In Lua, it's very easy to accidentally set a global variable when you don't mean to, and it looks like that's exactly what's happening.

function Enemies:new(enemies)
  enemies = enemies or {}
  timers = Timers:new()
  setmetatable(enemies, self)
  self.__index = self
  return enemies
end

On the third line here, since timers doesn't exist as a local variable here, this value ends up getting put into a global variable called timers instead. If you want to set a property of enemies, you need to mention enemies explicitly:

function Enemies:new(enemies)
  enemies = enemies or {}
  enemies.timers = Timers:new()
  setmetatable(enemies, self)
  self.__index = self
  return enemies
end

Now, you write:

But when I try to refrence one of the timers ( from inside the enemies object) , I am getting a nil value exception.

Lua doesn't really have any concept of being "inside an object" or "inside a class". In some languages, when you're writing code inside of a class, all of the class's members are in scope and you can refer to them "bare". Lua is not one of those languages; in Lua, if you want to refer to a "class member", you need to use the dot notation, explicitly stating which object you're accessing. (Or you can do the "advanced method", using _ENV.)

By the way...

timers = {} -- so that timers will be accessible in the class scope

From what I see in the question, this line doesn't do much; it just creates a global variable which is never used.

Also, this line in Enemies:new:

self.__index = self

This just sets Enemies.__index every time Enemies:new is called. This is fine, but you may as well just set it once:

function Enemies:new(enemies)
  enemies = enemies or {}
  enemies.timers = Timers:new()
  setmetatable(enemies, self)
  return enemies
end

Enemies.__index = Enemies
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.