lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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
>
>