lua-users home
lua-l archive

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


Chris Percival wrote:
> 
> Ok I give up, can someone give me a clear example of how to set a tag method
> for 'setglobal' for example?
> 
> For example something like this:
> 
>         lua_pushnumber(L, 1);
>         lua_setglobal(L, "Batch");
>         int tag = lua_newtag(L);     
>         lua_pushcfunction(L, SetglobalHander);
>         lua_settagmethod(L, tag, "setglobal");
> 
> This doesn't work, I guess I am missing something..  I know I have raised a
> couple of issues regarding this over the last week or so, but I just can't
> get anything going, and am getting frustrated.  There seems to be a huge
> lack of examples around even in the archives.  All the documentation around
> Lua is very terse, and doesn't seem to be geared to Lua newbies like me. :(

You have only set the tag-method for the 'setglobal' event of some new
tag to be the function 'SetglobalHander'.  As lhf said, you must also
explicitly tag the values that you want to be treated magically.  You
would use the function lua_settag for this.  The manual clearly states
that only userdata and tables can have new tags.

It's important to note that only values are tagged.  Variables contain
values, but it is the value that has the tag and therefor it is the
value that has the magic.  So if a variable has a value that doesn't
have any magic, it's a pretty dull variable, and not much is going to
happen.

All values have a tag which is just some number defined in lua.h

#define LUA_TUSERDATA   0
#define LUA_TNIL        1
#define LUA_TNUMBER     2
#define LUA_TSTRING     3
#define LUA_TTABLE      4
#define LUA_TFUNCTION   5

$ lua
Lua 4.0  Copyright (C) 1994-2000 TeCGraf, PUC-Rio
> print( tag(nil), tag(1), tag"", tag{}, tag(tag) )
1       2       3       4       5
> print(newtag())
9
> print(newtag())
10
> 

The example in the FAQ is interesting because it makes all function
values magical in that if you try to set a global variable that has a
function value, then the protect function will get called.

> function protect(x) error("cannot redefine "..x) end
>
> print(protect)
function: 0x8064ef0
> print(tag(protect))
5
> print(tag(foreach))
5
> settagmethod(tag(protect),"setglobal",protect)
> foreach = 99
error: cannot redefine foreach
stack traceback:
   1:  function `error' [C]
   2:  function `protect' at line 1 [string "function protect(x)
error("cannot redefine ..."]
   3:  main of string "foreach = 99" at line 1
> 

If you change the tagmethod to the print function, you can see what
arguments are passed to the tag method.

> settagmethod(tag(protect),"setglobal",print)
> 
> foreach = 999
foreach function: 0x8060ae8     999
> 

Remember that tag(protect) is nothing more that LUA_TFUNCTION which is
the number 5.  Now we see that when the tag method is called for the
pair (tag=5,event='setglobal'), it is passed three values: the variable
name, the old value of the variable, and the new value that you are
trying to set it to.  Just like the Lua Reference manual says on page
17.

If you want to protect only certain functions and not others, then set
the tag method for the 'setglobal' event for function values like so:

        lua_pushcfunction(L, SetglobalHander);
        lua_settagmethod(L, LUA_TFUNCTION, "setglobal");

And then use the variable name passed to SetglobalHander to decide if
you want to barf or not.

You should re-read page 14 of the Lua 4.0 reference manual very
carefully.  http://www.lua.org/ftp/

Good luck,

- Peter