[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] lua-Coat 0.2.0 : Yet Another Lua Object-Oriented Model
- From: François Perrad <francois.perrad@...>
- Date: Sun, 16 Aug 2009 15:30:20 +0200
2009/8/15 David Manura <dm.lua@math2.org>:
> On Fri, Aug 14, 2009 at 11:02 AM, François Perrad wrote:
>> lua-Coat is a Lua 5.1 port of Coat (http://www.sukria.net/perl/coat/),
>> a Perl module which mimics Moose (http://www.iinteractive.com/moose/),
>> an object system for Perl5 which borrows features from Perl6,
>> CLOS (LISP), Smalltalk and many other languages.
>> ...The homepage is at http://lua-coat.luaforge.net/,
>
>
> That seems to have some traction [3-4].
>
Yes, it's a port.
> In this syntax:
>
> require 'Coat'
> class 'Point'
> has( 'x', { is = 'rw', isa = 'number', default = 0 } )
> has( 'y', { is = 'rw', isa = 'number', default = 0 } )
> overload( '__tostring', function (self)
> return '(' .. self:x() .. ', ' .. self:y() .. ')'
> end )
> method( 'draw', function (self)
> return "drawing " .. self._CLASS .. tostring(self)
> end )
>
> the "end )" feels a bit awkward to write for every method in a
> program: it's a statement-level keyword (end) contained inside an
> expression-level ")", which tend not to mix in Lua. The "end" and ")"
> don't align to their matching start tokens, and the function block has
> less indentation than the "function" keyword. The original also
> involves quoting identifiers ('draw').
>
I agree. The syntax needs improvement.
I wrote small patches (see patch/) which allows a more perlish syntax.
I will send a specific message about them.
> It could be written in a more luaesque way a follows:
>
> require 'Coat'
> class 'Point'
> has.x = { is = 'rw', isa = 'number', default = 0 }
> has.y = { is = 'rw', isa = 'number', default = 0 }
> overload.__tostring = function (self)
> return '(' .. self.x .. ', ' .. self.y .. ')'
> end
> method.draw = function (self)
> return "drawing " .. self._CLASS .. tostring(self)
> end
> -- The above can also be written as such:
> -- function method.draw(self)
> -- return "drawing " .. self._CLASS .. tostring(self)
> -- end
>
> where "has", "overload", and "method" are tables, possibly with
> __newindex metamethods.
>
> I think self.x rather than self:x() tends to be the preferred syntax
> for object properties in Lua. This requires a proxy table though.
>
> Here's a few initial comments on the source:
>
>
>> module(..., package.seeall)
>
>
> I recommend avoiding package.seeall since it pollutes your external interface:
>
> require "Coat"
> print(Coat.math) --> table: 0x100549c8
>
Fixed in release 0.2.1
>
>> basic_type = type
>> local basic_type = basic_type
>> local function object_type (obj)
>> local t = basic_type(obj)
>> if t == 'table' and obj._CLASS then
>> return obj._CLASS
>> else
>> return t
>> end
>> end
>> _G.type = object_type
>
>
> This breaks type(). Consider:
>
Fixed in release 0.2.1
> require "Coat"
> require "someothermodule"
>
> where someothermodule internally applies type to a read-only table:
>
> local t = setmetatable({x=1}, {__index=function() error'read only' end})
> assert(type(t) == 'table')
>
> and now fails.
>
>
>> function _G.class (modname)
>
>
> This can then imply that other modules in your program cannot
> internally use Steve's class.lua module [1]. Consider this:
>
Yes, there is a conflict between them.
> -- b.lua
> require "class" -- internally uses class.lua
> .....
>
> which in turn is used by this:
>
> -- a.lua
> require "Coat"
> require "b"
> class "a" -- opps, invokes class.lua not Coat.lua
>
> I've had complaints about the Lua module system in the past [2].
>
>
>> function _G.class (modname)
>> checktype('class', 1, modname, 'string')
>> if _G[modname] then
>> error("name conflict for module '" .. modname .. "'")
>> end
>
>
> Is there a way to create anonymous classes? or lexically scoped
> classes? For example,
>
No. In fact, class 'Foo' acts like module 'Foo' (with some OO magic).
My current plan for release 0.3.0 is a support of submodule,
like class 'MyApp.Foo.Bar'.
Thanks for this great feedback.
François Perrad
> local class = require "Coat" . class
> local T =
> class(function()
> function method.test() print 'test' end
> end)
> T():test() --> test
>
>
> [1] http://lua-users.org/wiki/SimpleLuaClasses
> [2] http://lua-users.org/lists/lua-l/2009-08/msg00297.html
> [3] http://www.iinteractive.com/moose/
> [4] http://search.cpan.org/~drolsky/Moose/lib/Moose/Manual/Unsweetened.pod
>
>