lua-users home
lua-l archive

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


lhf escribió:

>>I am struggling a little with the following code
>>
>>  local g={}
>>  setfenv(0,setmetatable(g, {__index=_G}))
>>  ...
>>  for k,v in pairs(g)  do print(k,v) end

>>  lua5: t3.lua:9: attempt to call a nil value

> The problem is that g does not contain a function called "next", which 
"pairs"
> needs. You'll have to add it by hand:
>       local g={next=next}

Actually, the problem is that setfenv is changing the "global" or "C" 
environment
table. IMHO, that *should not be permitted* from inside a Lua script.

> The reason why "next" is not found when "pairs" is called is that 
"pairs" does
> a lua_rawget for "next" and so avoids the _index metamethod. Perhaps 
"pairs"
> should use lua_gettable instead of lua_rawget.

Or perhaps "pairs" should not rely on the global "next". If "next" were an 
upvalue
to "pairs", then the only thing that would change would be that a script 
which
wanted to redefine "next" would have to also redefine "pairs" and this 
would not
automatically be picked up by the "for" statement. On the other hand, the 
use of
iteration "for" statements with implicit "pairs" is deprecated, as I 
understand it.
In any event, it would have worked as the author intended, in this 
example.

I think it is cleaner if the C environment is reserved for use by C 
functions.
Then you do not have to worry about not including "next". However, if you 
are
going to change the global environment, you probably need to worry about 
the
following:

next ipairs __pow tostring print _TRACEBACK

unless I'm forgetting something. Some of these only matter to the 
standalone
interpreter.

Rici.