[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: getting upvalues in current thread's environment?
- From: "Matthew Armstrong" <turkeypotpie@...>
- Date: Sun, 28 Jan 2007 12:56:12 -0800
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