Local variables in the main block are global

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Local variables in the main block are global

Dirk Laurie-2
Try this:

~~~ file localisglobal.lua
setmetatable(_ENV,{__newindex = function (ENV,name,value)
   if name:match"^%a%d?$" then
      print(": A global name like '"..name.."' is asking for trouble")
   end
   rawset(ENV,name,value)
end})

local Y=2
~~~

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Dirk Laurie-2
Sorry, hit the sent button too soon. The behaviour of the
title occurs in a long module of mine, and I am still trying
to isolate it. It's not that simple. Sorry!

2013/4/21 Dirk Laurie <[hidden email]>:

> Try this:
>
> ~~~ file localisglobal.lua
> setmetatable(_ENV,{__newindex = function (ENV,name,value)
>    if name:match"^%a%d?$" then
>       print(": A global name like '"..name.."' is asking for trouble")
>    end
>    rawset(ENV,name,value)
> end})
>
> local Y=2
> ~~~

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Dirk Laurie-2
2013/4/21 Dirk Laurie <[hidden email]>:
> Sorry, hit the sent button too soon. The behaviour of the
> title occurs in a long module of mine, and I am still trying
> to isolate it. It's not that simple. Sorry!

Turns out I have been too clever for my own good.

My module loads another module written in C. That module has a tiny bit
of initialization code in Lua. I use a global variable also called
'X' in there; I delete it immediately, but the bug detector picks it up.
The C file ends something like this:

~~~
char *mymodule_init =
"for k,v in pairs(_G) do X[k]=v end "
"X=nil"
;

LUAMOD_API int luaopen_mymodule_core (lua_State *L) {
  luaL_newlib(L, myfuncs);
  lua_pushvalue(L,-1); lua_setglobal(L,"X");
  (void)luaL_dostring(L,mymodule_init);
  return 1;
}
~~~

Actually, I have not been clever at all. Global variables with one-letter
names are hazardous even in initializion code in a C module, The bug
detector in my original accidental post does exactly what it should.

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Dirk Laurie-2
2013/4/21 Dirk Laurie <[hidden email]>:

> 2013/4/21 Dirk Laurie <[hidden email]>:
>> Sorry, hit the sent button too soon. The behaviour of the
>> title occurs in a long module of mine, and I am still trying
>> to isolate it. It's not that simple. Sorry!
>
> Turns out I have been too clever for my own good.
>
> My module loads another module written in C. That module has a tiny bit
> of initialization code in Lua. I use a global variable also called
> 'X' in there; I delete it immediately, but the bug detector picks it up.
> The C file ends something like this:
>
> ~~~
> char *mymodule_init =
> "for k,v in pairs(_G) do X[k]=v end "
> "X=nil"
> ;
>
> LUAMOD_API int luaopen_mymodule_core (lua_State *L) {
>   luaL_newlib(L, myfuncs);
>   lua_pushvalue(L,-1); lua_setglobal(L,"X");
>   (void)luaL_dostring(L,mymodule_init);
>   return 1;
> }
> ~~~
>
> Actually, I have not been clever at all. Global variables with one-letter
> names are hazardous even in initializion code in a C module, The bug
> detector in my original accidental post does exactly what it should.

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Dirk Laurie-2
2013/4/21 Dirk Laurie <[hidden email]>:
> 2013/4/21 Dirk Laurie <[hidden email]>:
>> 2013/4/21 Dirk Laurie <[hidden email]>:
>>> Sorry, hit the sent button too soon.

And again. Should have slept late instead of getting up early
on a Sunday morning.

The point of the previous post should have been that Lua
startup code is not what triggers the bug detector. It is
triggered by the C code itself in "lua_setglobal(L,"X");"

This is something I did not know: that the C API can be
that aware of something done in the calling Lua program.
Setting a metatable hooks in very low down!

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Owen Shepherd
Dirk Laurie wrote:

This is something I did not know: that the C API can be
that aware of something done in the calling Lua program.
Setting a metatable hooks in very low down!


The C API mirrors Lua behavior pretty closely. If you don't want metatables triggered... well, thats what rawset is for.

My general preference for "hybrid" modules is to pass the extra data as parameters to the module and do something similar to
    local x, y, z = ...
as the first line of code.

I wish that, for this purpose, Lua had a feature like most JavaScript interpreters do which lets you say "This fragment of code has these parameters" and let you give them names.
Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

joao lobato


On Apr 22, 2013 4:29 PM, "Owen Shepherd" <[hidden email]> wrote:
>
> [snip]
>
> I wish that, for this purpose, Lua had a feature like most JavaScript interpreters do which lets you say "This fragment of code has these parameters" and let you give them names.

So, you want functions...

Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

steve donovan
On Mon, Apr 22, 2013 at 9:25 PM, joao lobato <[hidden email]> wrote:
So, you want functions...

Heh, well put!  It would be nice if dofile() was allowed to pass arguments to the main chunk. E.g. we have 'dofile.lua' which is just:

print (...)

dofile() won't pass any arguments  - but it's easy to write a dofile which does take arguments:

> c = loadfile 'dofile.lua'
> c('one',1,20)
one     1       20

BTW, there is a little diffference between require() on 5.1 and 5.2:

> require 'dofile'
dofile  .\dofile.lua

That is, also passes the filename as well as the module name.

steve d.


Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Owen Shepherd
steve donovan wrote:

On Mon, Apr 22, 2013 at 9:25 PM, joao lobato <[hidden email]
<mailto:[hidden email]>> wrote:

    So, you want functions...


Heh, well put!  It would be nice if dofile() was allowed to pass
arguments to the main chunk. E.g. we have 'dofile.lua' which is just:

print (...)

dofile() won't pass any arguments  - but it's easy to write a dofile
which does take arguments:

> c = loadfile 'dofile.lua'
> c('one',1,20)
one     1       20

BTW, there is a little diffference between require() on 5.1 and 5.2:

> require 'dofile'
dofile  .\dofile.lua

That is, also passes the filename as well as the module name.

steve d.




Right, but what I was wishing for was the ability to name the parameters passed to the function returned by load()

An example of the usage of this can be seen along the lines of HTML event handlers: Imagine an excerpt from a HTML document using Lua instead of JavaScript:
   <button onclick="table.insert(eventLog, ev)">Name</button>
Browsers use the JavaScript functionality to load a fragment of code as a function with named parameters to inject variables like "ev" into the function's scope.
Reply | Threaded
Open this post in threaded view
|

Re: Local variables in the main block are global

Philipp Janda
Am 25.04.2013 05:04 schröbte Owen Shepherd:

>
> Right, but what I was wishing for was the ability to name the parameters
> passed to the function returned by load()
>
> An example of the usage of this can be seen along the lines of HTML
> event handlers: Imagine an excerpt from a HTML document using Lua
> instead of JavaScript:
> <button onclick="table.insert(eventLog, ev)">Name</button>
> Browsers use the JavaScript functionality to load a fragment of code as
> a function with named parameters to inject variables like "ev" into the
> function's scope.
>

What about

     loadstring( "local eventLog, ev = ...\n" .. "table.insert(eventLog,
ev)" )( eventLog, ev )

?

Philipp