[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: setfenv/getfenv
- From: Richard Hundt <richardhundt@...>
- Date: Tue, 12 Jan 2010 18:29:40 +0100
Roberto Ierusalimschy wrote:
I will try to answer the sereval requests for our rationale for the
removal of setfenv/getfenv.
I'm happy using debug.getfenv/setfenv instead of the deprecated globals
- but pretty please don't remove these as well. Just to throw some use
cases into the pot for consideration...
I find myself needing to access module function environments for symbol
import/export (Perl style -- i.e. controlling the exportable symbols via
a list from the module being imported).
For OO; creating a function environment scoped "super" function which
delegates to the parent class' method of the same name -- naive code:
add_method(Point3D, "move", function(self, x, y, x)
super(self, x, y) -- injected into this environment by add_method()
end)
Control member access to a table/object depending on a caller's
environment. In other words, sometimes you want to associate arbitrary
data with a function (which can be hidden, if string keys are avoided),
in this case so that you can ask: "is my caller marked for access to
this resource?" -- more naive code:
local access = { }
local data = { }
setmetatable(object, {
__index = function(_, key)
local outer = getfenv(2)
if outer[access] and outer[access][key] == object then
return rawget(data, key)
end
error("permission denied to access: "..tostring(key))
end
})
... where the caller function would need to have its environment
suitably cooked with a fenv[access][key] = object. This is particularly
convenient when you want to mark all functions in a module/class; doing
it using tables will be pretty clunky in comparison.
There are probably other ways of doing the above, but although I really
like the "in expr do ... end" construct (and I'll definitely be using
it), I'll continue to (ab)use (debug.)getfenv/setfenv for a fair portion
of my "make your own batteries" stuff.
Rich