Search code examples
classluasettergettercodea

Lua getters and setters


I'm working with the Codea iPad app and learning Lua. Codea uses Class.lua for classes. What I'm trying to achieve is a way to specify functions for a variables get and set methods. Currently, a variable say "x" can be accessed liked this: print(obj.x) and set with code like this: obj.x = 1. I would like for the variable to instead call a get and set function I can specify. I'm porting something written in Actionscript 3 and need to mimic A3's get and set function declarations. Let me know if this is possible or if their is another way. I can override Codea's Class.lua if adding or altering its code is a solution. Thanks.


Solution

  • You can create a custom setter and getter by overriding the __newindex and __index methods on your class.

    Note that you'll have to modify LuaSandbox.lua, which is part of Codea, to enable the rawset and rawget methods (comment out the lines setting them to nil). EDIT: This is no longer the case in the latest version of Codea, rawset and rawget are available by default.

    The __newindex method gets called whenever you attempt to set a property on the table that has not been set before.

    The __index method gets called whenever you attempt to get a property that does not exist in the table.

    So you can insert custom code for getters and setters by creating a private table in your class, and storing your member variables in there. When you attempt to read and write them, you can execute custom code in your __newindex and __index methods.

    MyClass = Class()
    
    function MyClass:init()
        -- We'll store members in an internal table
        self.members = {}
    end
    
    function MyClass:__newindex( index, value )
        if index == "testMember" then
            self.members[index] = value
            print( "Set member " .. index .. " to " .. value )
        else
            rawset( self, index, value )
        end
    end
    
    function MyClass:__index( index )
        if index == "testMember" then
            print( "Getting " .. index )
            return self.members[index]
        else
            return rawget( self, index )
        end
    end
    

    To test it

    function setup()
        foo = MyClass()
    
        foo.testMember = 5
        foo.testMember = 2
    
        print( foo.testMember )
    end
    

    You can find more information about metamethods here: http://lua-users.org/wiki/MetamethodsTutorial