[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: OOBit
- From: Nilson <nilson.brazil@...>
- Date: Fri, 1 Oct 2010 13:16:06 -0300
Hi guys,
On Fri, Oct 1, 2010 at 6:02 AM, steve donovan <steve.j.donovan@gmail.com> wrote:
> On Fri, Oct 1, 2010 at 10:27 AM, Miles Bader <miles@gnu.org> wrote:
>> fact that it adds more "magic" makes me take take pause; it feels like
>> something that might be one of those "good ideas" which seems
>> appealing at first, but turns out to be a ball of hair in the long
>> run.
>
> I'm with you on that; there are remarkably few gotchas in Lua. A
> well-written library will know that people will make a dot/colon
> confusion and will be able to issue a 'bad self' message - maybe even
> say 'you forgot the colon!'
>
Sorry. I swear I've tried to keep silent but I think that I have the
duty to clarify misunderstood concepts about the patch.
Please, watch the examples below (sent to me by a PenPal):
Super = {
new = function (o)
o = o or {}
o.x = 10 -- constant default
return o
end,
}
Sub = setmetatable({}, { __index = Super})
function Sub:new (o) -- COLON (syntactic sugar)
o = Super.new () -- DOT. COLON will fail
o.y = 2 -- DOT
return o
end
o1 = Sub.new() -- DOT
print(o1.x, o1.y) -- DOT
If you add an "class" default_x , it should be changed to:
Super = {
default_x = 10,
new = function (self, o) -- Cannot you colon
o = o or {}
o.x = self.default_x -- "class" default
return o
end,
}
Sub = setmetatable({}, { __index = Super})
function Sub:new (o) -- COLON (syntactic sugar)
o = Super:new (o) -- now COLON is OK
-- but could be o = Super.new(Super,o) -- DOT
o.y = 2 -- DOT
return o
end
o1 = Sub.new() -- DOT
print(o1.x, o1.y) -- DOTs
Note that "new" acts like a "constructor" but not a classical one
because constructors usually can be seen as a special METHOD of a
class and therefore should receive the CLASS as the self, as became
necessary in ** part ** of example 2. As Lua gives you the power to
make it in different ways, people use it.
Now, suppose you *** chose *** to use a consistent OO Java-like
approach in your brand new Lua software. How OOBit could help?
Super = {
default_x = 10,
new = method (o) -- class method
o = o or {}
o.x = self.default_x -- Self is the Class
return o
end,
}
Sub = setmetatable({}, { __index = Super})
method Sub.new (o) -- DOT
o = Super.new (o) -- DOT
o.y = 2 -- DOT
return o
end
o1 = Sub.new() -- DOT
print(o1.x, o1.y) -- DOT
As OOBit offers you a way to consistently use of the DOT, it drives
you gently to a conventional-Java-style OO usage, as you can see
above, where all constructors seem to be naturally used as class
methods.
If you ** chose ** to work using a Java like OO approach, you ** may**
let the patch help. Believe, it will help a lot.
If you prefer a "classical" approach in your projects, just do not
create METHODs. You will never know that OOBit exists.
And don't worry too much about performance impact. I already have a
alpha version running and the impact on performance is negligible -
mainly in function calls with some parameter passing. You may
benchmark it later when I release the beta. Lua's runtime is
remarkably simple and beautifully efficient, which helps a lot. ** I
would like some help in varargs stack handling **.
By the way, OOBit does not require a keyword like METHOD. It is just a
syntactic sugar:
method a.b( etc) ... end <=> function a.b (self, etc ) ...end;
a.b = ooset(a.b)
I use the keyword because I think it is more compact and quite
expressive. I could have used a double colon " :: " as a ** super
syntactic sugar **, for example.
And finally, when your project needs to call a "classic" library, you
must use the notation recommended by the library's manual. OOBit does
not interfere with non "ooseted" functions.
I think that incompatibilities could arise only when:
a) you pass a new METHOD that you written to a classical library and
b) internally, the classical library make one of these kinds of call
- obj.METHOD(obj, etc) meaning " obj:METHOD(etc) " or " METHOD(obj,etc) "
- obj.METHOD(obj2,etc) meaning " tmp = obj.METHOD; tmp(obj2,etc) "
I believe this would rarely occur (If you are a library writer, you
could help a eventual community of OOBits users avoiding constructions
like these).
To solve these kind of incompatibility, you could encapsulate the function:
Consider the "demanding'" library function: " library_function(func) "
To use it you could write
library_function(function(...) return your_method(...) end)
or create a permanent encapsulated
a_compatible = function(...) return your_method(...) end
and then call
library_function(a_compatible)
I implemented OOBit in a different way, but If necessary I could
return to the original idea to may do:
a_compatible = oounset(your_method)
As a simple assignment that clears the OOBit on value your_method
before assign it to a_acompatible.
It's also possible to create a way to mark "demanding" functions,
although it will increase a little bit the execution time. In that
case, you could just execute:
ooclassic(library_function)
Now, the patch will ignore the OOBit status during a library_function
call, so you could do:
library_function( your_method )
with no worries.
But remember, it would be necessary to occur (a) and (b) to have to
handle this kind of problem.
Sorry if this message still contains any errors. I limited the number
of reading and revision in five.
As I always guard against the Shakespeare's language, I apologize in
advance. :-)
Cheers,
Nilson