lua-users home
lua-l archive

Re: getting upvalues in current thread's environment?

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


Setting the environment explicitly works, but that doesn't really help me write the tighter syntax that I want.
For instance, this does allow me to use the syntax I want:

function getEnv()
local env = {}
local i = 1
while true do
local localVar, value = debug.getlocal(3, i)
if localVar ~= nil then
env[localVar] = value
else
break
end
i = i + 1
end
setmetatable(env, {__index = _G})
return env
end

function eval(s)
local f = assert(loadstring(s))
setfenv(f, getEnv())
f()
end

function flarp()
local myLocal = "hello"
eval[[print(myLocal)]]
end

flarp()

(prints hello)

... but it uses the debug library and has a nice fat function call overhead.


On 1/17/07, Sam Roberts <sroberts@bycast.com> wrote:
On Tue, Jan 16, 2007 at 10:53:47PM -0800, Matthew Armstrong wrote:
> Cool, thanks for your help.
>
> The reason I asked is I want to try to mimic "eval" functionality, found in
> some other scripting languages, such as perl.
>
> Lua has loadstring, but this operates in the global environment, and
> afaik/remember, perl puts more context into its eval.

With lua, you put the context in after, with setfenv().

> All I'm really going for here is tighter syntax, as I'm trying to adapt lua
> into a sort of higher level language to suit our purposes.
>
> For instance, we have a trigger object, which will fire when a certain event
> occurs. One specialization of the trigger is a conditional version, which
> fires when a particular condition is true. Creating a conditional trigger
> looks something like this:
>
> TCond(function() return a > b end)
>
> but I'd like to shorten it to:
>
> TCond[[a > b]]

...

> But I'm running into trouble, because loadstring can't access local
> variables 'a' and 'b' in the environment.


Technically, where a and b are isn't an environment, not as lua uses the
term "environment", but instead of making a and b local, and instead of
making them global, put them into a function environment specific
to the evaluation of the condition?

Then the TCond<code> has its own environment it can operate in, you can
specify exactly what will appear there, including preventing global env
access, if you wish.

Clunky example:

> function f() p = loadstring"print(a)"; setfenv(p, {a='hello',print=print}); p(); end
> f()
hello

or

state = {a=1, b=2}
function TCond(trigger) condition = loadstring('return '..trigger); setfenv(condition, state) end
print(condition())

Sam



AltStyle によって変換されたページ (->オリジナル) /