[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: Tue, 18 Aug 2009 22:40:30 +0200
2009/8/16 François Perrad <francois.perrad@gadz.org>:
> 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.
>>
Now, lua-Coat is fully refactored with this syntax.
But not yet released, see HEAD on http://github.com/fperrad/lua-Coat/
New comment wellcomed
>> 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.
>>
the attribute setter is : self:x(val)
so the attribute getter must be : val = self:x()
In fact, self.x is the getter/setter function.
François.
>> 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
>>
>>
>