lua-users home
lua-l archive

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


2010/9/30 Patrick Donnelly <batrick@batbytes.com>:
> (Forgive me if someone has noted this before; I don't recall any
> discussion on it.) It recently occurred to me that you can use _ENV to
> setup methods that look like popular object oriented languages (such
> as Java). For example:
>
> function Class:Method (bar)
>  local _ENV = self;
>  foo = bar -- assign self.foo = bar
> end
>
> This isn't easily doable in Lua 5.1 because environments are set on
> the function itself (and would change the method for all objects)
> whereas in the above case this only changes the method environment for
> the given execution frame.
>
> You can also automate this process by doing:
>
> function Class.Method (_ENV, bar, x)
>  foo = bar -- assign self.foo = bar
>  _ENV.x = x -- names collide, similar to this.x = x in Java
> end
>
> I thought this was a pretty neat side effect of the new environments
> for Lua 5.2 and worth sharing. The _ENV name makes it confusing for
> beginners since the name doesn't make a whole lot of sense. It also
> complicates getting global functions like pairs.

In the first case, you can circumvent the problem by replacing [[
local _ENV = self ]] with [[ local _ENV = wrap(self) ]] where wrap
will return a proxy that reads from _G but writes to self.

And with a simple token filter, you could even leave the line out. For
example with a new "method" keyword :

method Class:Method (bar)
    foo = bar -- assign self.foo = bar
end

would be equivalent to :

function Class:Method (bar)
    local _ENV = wrap(self)
    foo = bar -- assign self.foo = bar
end