lua-users home
lua-l archive

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

Rici Lake wrote:

On 26-Aug-05, at 9:35 AM, Chris Marrin wrote:

    Function MyClass:f(v) a = v end

then you could go:

    local instance = MyClass()

and when f(v) runs, the __setindex metamethod would get called with the parameters of the common function environment, the property 'a' and the value 'v'. This __setindex method can then go up to the next function to the stack and find the 'self' reference as the first param. It can then look up 'a' in this reference, set its value to 'v' and you're done. A nice object-oriented mechanism for handling instance local access.

Isn't this a complicated way of confusing the difference between instance and class members? I would have thought that:

  function MyClass:f(v) self.a = v end

was not much harder to type and quite a bit more self-documenting.

I'm aware that some languages do perform this sort of scoping exercise, so I guess some people must like it. I think it also leads to obscure bugs.

That doesn't avoid the self confusion error which you noted.

However, in many cases you can avoid the problem by using get/set notation instead of methods. If the user interface were:

  obj.f = v

instead of


then there would be no possibility of programmer error, and it would have the advantage of letting you define both an f-setter and an f-getter. (Or the disadvantage of forcing you to :) Anyway, that was the motivation for the library for which I sent you an excerpt.

This doesn't work in the case of setters which require more than one argument, or getters which require arguments. But that's not the common case (although it's not a rare case, either).

All good points. It is becoming clear that, while Lua is well suited to doing just about anything (just like assembly language :-), it will never be a true object-oriented language. There will always be ':' vs. '.' issues, places where the language just can't express an object-oriented relationship (as in the case where you just HAVE to supply an explicit 'self' argument) and the fairly quirky way that some of the metamethods work.

Don't get me wrong, I think Lua is a fantastic tool and I would never consider another language for my app. But I am really trying to do two things with Lua. First, I am using it as a basic scripting technique to get my app on the air faster. But my system is declarative and therefore I need to expose scripting to creative authors who are not experienced programmers. So I need to make the language as simple and understandable as possible.

Just to harp on another issue, I was very proud when I overrode all the arithmetic opcodes to be able to handly my "primitive objects". My system has objects, for instance SFFloat, which are wrappers around primitives (float in this case). If I have:

    local a = SFFloat(1)

I really want to go:

    local b = a + 5

So I overrode __add and simply converted the object to a primitive, did the add and returned the result. Cool! Well, when I overrode __lt so I could do this:

    if a < 5 then ...

it didn't work because the logic around __lt requires that both sides of the operator are the same type! I mentioned this on the list before and had to make a small patch to get this to work. But then I wanted to do this:

    local c = SFBoolean(true)
    if c then ...

and that didn't work at all. SFBoolean is a wrapper around a bool, but Lua sees it as a userdata and the l_isfalse() test simply checks if it is a Lua boolean value, so this always tests as false. It would be nice if there were __toboolean and __tonumber metamethods, just like there is __tostring.

I have had to resort to a valueOf() method on these objects. So you have to go:

    if c:valueOf() then ...

not bad, but not very friendly to the authors either!

Anyway, thanks for engaging on this issue.

chris marrin                ,""$,          b`    $                             ,,.
                        mP     b'                            , 1$'
        ,.`           ,b`    ,`                              :$$'
     ,|`             mP    ,`                                       ,mm
   ,b"              b"   ,`            ,mm      m$$    ,m         ,`P$$
  m$`             ,b`  .` ,mm        ,'|$P   ,|"1$`  ,b$P       ,`  :$1
 b$`             ,$: :,`` |$$      ,`   $$` ,|` ,$$,,`"$$     .`    :$|
b$|            _m$`,:`    :$1   ,`     ,$Pm|`    `    :$$,..;"'     |$:
P$b,      _;b$$b$1"       |$$ ,`      ,$$"             ``'          $$
 ```"```'"    `"`         `""`        ""`                          ,P`
"As a general rule,don't solve puzzles that open portals to Hell"'