OOP and modules

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

OOP and modules

David Haley

Hi list,

I've been converting some code to a proper package structure. Since it's still 5.0.2 code, I'm using the compat-5.1 code which has been working beautifully.

Previously, when defining a class, I would do something like this:

ParseTree = {}

function ParseTree:new(name, transitionRecord)
   local o = {}

   setmetatable(o, self)
   self.__index = self

   return o
end

which is, IIRC, the technique given in PIL to implement classes.

But with modules, this all becomes tedious. I'd have to do something like:

require ("clip.parsetree")
parsetree = clip.parsetree.ParseTree:new()

which seems a bit excessive to me.

My solution is to do the following:

module ("clip.parsetree")

function _M:new(name, transitionRecord)
assert( self == _M, format("You need to call %s:new(), not %s.new()!", _NAME, _NAME ) )

   -- normal stuff follows as above...
end


This seems to work, and I can now do:
require ("clip.parsetree")
parsetree = clip.parsetree:new()

which is what I wanted.

Is this the "right" way of implementing classes in modules? Is there a better way? Is there something wrong with this approach that I should be aware of?

Thanks much.
Best,
David

--
~David-Haley
http://david.the-haleys.org



Reply | Threaded
Open this post in threaded view
|

Re: OOP and modules

Tomas-14
	Hi David

module ("clip.parsetree")

function _M:new(name, transitionRecord)
assert( self == _M, format("You need to call %s:new(), not %s.new()!", _NAME, _NAME ) )

  -- normal stuff follows as above...
end
	You could omit the _M (but then you'll have to write the implicit
`self'):

function new (self, name, transitionRecord)
...

This seems to work, and I can now do:
require ("clip.parsetree")
parsetree = clip.parsetree:new()

which is what I wanted.

Is this the "right" way of implementing classes in modules? Is there a better way? Is there something wrong with this approach that I should be aware of?
	I think there is nothing wrong with your implementation.
	I would like to add that if you want some inheritance, you could
use the second argument of `module()' to achieve an elegant solution.
Let's define a basic object class:

local setmetatable = setmetatable
module"obj"
function inherit (self)
    return function (newclass)
        setmetatable (newclass, self)
        self.__index = self
        return newclass
    end
end
function new (self, o)
    o = o or {}
    setmetatable (o, self)
    self.__index = self
    return o
end

	Now you can define a new class which extends the previous `obj':

local obj = require"obj"
module ("myobj", obj:inherit())

	Class `myobj' will "inherit" the methods `new' and `inherit'
from class `obj'.
		Tomas

Reply | Threaded
Open this post in threaded view
|

Re: OOP and modules

David Haley

Hi,

On this day of 3-12-2006 6:04 PM, Tomas saw fit to scribe:
    I think there is nothing wrong with your implementation.
    I would like to add that if you want some inheritance, you could
use the second argument of `module()' to achieve an elegant solution.
Let's define a basic object class:

[...]

Lovely, this is exactly what I wanted to do next. Thank you for your reply and sorry for the delay on my part; haven't had a chance to play around with Lua in the past couple of weeks.

Thanks again,
David


--
~David-Haley
http://david.the-haleys.org