Singleton Oop Question

Hello, I was wondering if there really is a way to use the Singleton method using tables. I’m not sure if it’s possible, because Lua doesn’t have static variables. And if you were to do a require(“MySingletonFile”) wouldn’t it always return a new instance? Or do tables have the same instance no matter what requires them? Hope that was clear enough…

In most cases the simplest thing is just creating a global variable requiring your module - don’t worry about using a global once in a while, as long as it’s not used in intensive for-loops (in which cases you can easily substitute it with a local var temporarily).

So basically just say:

[lua]

myGlobal = require(“mySingletonFile”)

[/lua]

I know it’s a simple answer, but that’s the way I do it. Let me know if you something more sophisticated for some reason.

Okay, well I did some testing, and this is what I came up with. I made a little program to test this.

module.lua

[lua]

local m = {}

m.t = “HELLO WORLD”;

local i;

if not i then

    i = setmetatable({}, m);

end

return i

[/lua]

main.lua

[lua]

local i = require(“module”)

print(i);

local h = require(“module”)

print(h);

[/lua]

And this is the output.

table: 0x7fc99a4088b0

table: 0x7fc99a4088b0

So it appears they are the same table. Am I missing something to as how tables work?

this is the way i do it inside of my OO modules:
 
[lua]
 
– at beginning of module
local autostore_singleton = nil
 
– at end of module
if autostore_singleton == nil then
  – do any setup necessary for your object/table
    autostore_singleton = AutoStore:new()
    autostore_singleton:init()
    autostore_singleton:load()
end
return autostore_singleton
[/lua]
 
this works because the code inside of a module is run only once on the first require() even though there might be several of them inside of an app. the module loader simply saves the module return value and uses that for any subsequent module require().
 
so, what @thomas6 suggests will work for simple tables because of this fact. however, if you are using OO with an object constructor (e.g., new() ), then you will have to do something similar to what i suggest.
 
cheers,
dmc
 
ps, the example was taken from my library module dmc_autostore if you want to check out the entire code file: https://developer.coronalabs.com/code/dmc-lib-auto-store .

jake, your second example is similar to the one i suggested and it works. so why do you think that you’re missing something ?

cheers,
dmc

hi Jake,

I’m only following this with half my attention, but for a singleton you shouldn’t need to use metatables at all, in my opinion - although I’m very curious to hear what dmccuskey thinks of this --> dmc, you’re my OOP mentor as far a Lua goes! Massive respect :wink:

Ah, okay. I was trying to kinda follow how I did it in Java… But looks like I don’t even need to have a getter in my class for the instance of another if I’m not wanting multiple instances… I’m actually using and really liking your OOP library. Really helpful. :smiley:

I guessed I was just confused as to how modules work in Lua. When you require them does it re-execute the code every time, or not. But if the return value is just saved in the require, then do you even need the [lua]if not i then i = setmetatable({}, m) end [/lua] because that is not run every time…

From the way I’ve seen it. When you do i = m it just references m when you call i. So setting a meta table copies a table. Tell me if I’m wrong, but thats what someone told me awhile ago…

Hey Jake,

Setting the metatable of one object to another object, is like saying: “if you don’t find a certain function or property in this objects metatable, then go look for it in the other objects metatable”. From there on it becomes simple: if you create 20 ‘empty’ objects, and assign all of them the metatable of a ‘prototype’ object, then these 20 objects will actually practically become instances of this one base object or class. OOP in Lua in a nutshell.

But the thing is, if you only want to use a singleton class, you just need this base object with its own functions and properties, and you don’t need setting metatables, since this would only make sense if you want a second or third object to behave like your singleton - in which case we’re not talking about singletons anymore.

Man, it was confusing to me at first, but I’m starting to love Lua’s OOP more and more each day!

Ah okay, but am I right that just saying table 1 = table 2 just references table 2. So this works…

[lua]

local m = { “hey” }

local j = m

print(m[1])

j[1]=“hey2”

print(m[1])

[/lua]

output:

hey

hey2

Yep, variables get copied over into the new variable with = , but tables just get referenced. Confusing at first if you want an independent copy, but really practical because this allows you to make a local version of a global table (in this case, your singleton) for use in code-intensive blocks.

LOL. :smiley: thanks, Thomas !

i think what it boils down to is what type of object Jake wants to create.

the type thomas is suggesting is a completely valid object – a single table with properties and methods assigned to it. in a sense though it is *already* a singleton because the intent is *not* to create other instances of it using new(). ( thomas, correct me if i’m wrong ). so it’s a perfect solution.

because Jake started to use the setmetable() method, i thought that perhaps it was the beginning of a more complex object because (like Thomas said) that’s the reason why you would use setmetable().

what i’m suggesting is for those situations when a singleton is required, but the module *does* allow other instances to be created. this is the situation that the Singleton Pattern solves. for example, you might use a storage/database module which allows multiple database files, but you want to make sure that your app only uses one.

now, technically because you have the code for these modules, you *could* go and make modifications directly to them, but it’s cleaner and easier just to wrap that module in one of your own and use some singleton-esque code to constrain the object creation.

You’re very welcome! By the way, I’m a designer by profession, 20 years of Photoshop, Illustrator and 3D experience, so if I can return the favor somehow, let me know!

Yeah, and I’m coming from a Java perspective on the whole thing, which is like the situation you describe. I’m using your dmc_objects library for my OOP, and while it would be nice to have it be able to have other instances be created from it in the future, its not entirely needed. But I’m still wondering why I need to have the if nil then make a new instance, else just return the current instance, is Lua just saves the return anyways and doesn’t execute that code again.

hmmm. i guess you’re right – you could get rid of the if/then part and leave the initialization code by itself and return afterwards. if no initialization is necessary then you could even get rid of the variable and return from the new().

Which variable and return?

wow, i’d say a senior designer such as yourself with good programming skills is a deadly combination. :slight_smile: you can truly create anything. props to you !

my only design skills come from my copy of OmniGraffle. that app is indispensable because it makes it seem like i have more design talent than i really do. LOL

i will definitely keep you in mind. :slight_smile:

sorry about that. this is what i was considering:

[lua]
– if you need to initialize:

local singleton = MyClass:new()
singleton:init()
singleton:load()
return singleton

– if no initialization is required:

return MyClass:new()
[/lua]

Ahh, that makes more sense. :slight_smile: This is why I was asking, I was going to have in my main.lua a class that held the main game engine. The main class would be singleton but the game engine class wouldn’t be. But from the looks of this I could just make the GameEngine class singleton and be done with it… lol