Question

My goal is to write an addon for a GUI written in Lua. It should replace the creation of a window without the need of changeing the code of the GUI itself. The original function creating the window looks like this:

function GUIclass.createWindow(arg1, arg2, arg3, arg4, arg5)
    -- do stuff
    return window
end

My method looks like this:

function MyClass.createWindow(arg1, arg2, arg3, arg4, arg5)
    local foo = self.attributeOne -- doesn't work, as self is undefined
    -- do some more stuff wich requires foo
    return window
end

... and later on
MyClassInst = MyClass:new()

Note that both functions are in different files. The idea I had was replacing the pointer to the old function after it has been initialised

GUIclass.createWindow = MyClass.createWindow

Everything works fine, except I seem to be unable to get a reference to the instance of MyClass in MyClass.createWindow. I tried using

local self = MyClassInst

in the MyClass.createWindow but it is nil. I also dislike this because it is limited to one instance of the Class. As stated in the title, ":" also woun't work as the function gets called via "GUIclass.createWindow(args)" (which now points to MyClass.createWindow).

So how can I get a reference to the instance of a class without using ":"?

Was it helpful?

Solution 2

If you're creating a new window object, there's no need for a self parameter. Instead, create the new instance within the MyClass.createWindow function. Do this either by using a table constructor ({}) or by calling another constructor function. Example:

local oldCreateWindow = GUIclass.createWindow
function MyClass.createWindow(...)
  local window = oldCreateWindow(...)
  local foo = window.attributeOne
  -- do some more stuff wich requires foo
  return window
end

I think I understand your problem better now. I believe you'll be better off with a closure than with a class.

-- MyClass is actually just a table with lots of attributes that change a lot.
local MyClass = {}
local function createWindow(arg1, arg2, arg3, arg4, arg5)
  local foo = MyClass.attributeOne
  -- do some more stuff wich requires foo
  return window
end

GUIclass.createWindow = createWindow

After that, any changes you make to MyClass should be visible to GUIclass.createWindow.

OTHER TIPS

I'll just post as an answer..

Try:

function MyClass.createWindow(self, arg1, arg2, arg3, arg4, arg5)

As far as I remember from lua, that equals:

function MyClass:createWindow(arg1, arg2, arg3, arg4, arg5)

Just like

class:something()

equals

class.something(class)

You can't (mostly) that's sort of the point of what : does for you here.

If you are calling the function with a . you don't have any context for the call other than the arguments you give it (and any closed-over variables that function has).

If you wanted to create multiple instances of your custom createWindow function you could have them close over some class instance variable and use that internally but you would have to do that manually and have the classes available before-hand. I don't know if that is doable in your situation or not.

I also don't really understand the issues with the code as written.

Are you expecting to have more than one custom createWindow function that monkey-patch in to GUIclass repeatedly as appropriate? Or why would you need createWindow to take a self argument the way you've written it?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top