lua-users home
lua-l archive

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


Dimitris escibió:

> I don't want my C vars to be local but I want to be able to assign
> values to them the usual way and not interfere with gloabal lua vars.
> I set the "settable" method for the globls table but my method gets
> called only when I assign to my C exported var(a userdata var that
> is).That's what I want but is that normal or am I doing something
> wrong?What if I set the setglobal and getglobal tag methods for my
> userdata C vars?Wouldn't that do the job?

Yes, it would. In Lua 4, that's the way to do it.

Peter Hill anadió:
> > In Lua4 there was special treatment for global accesses. As globals are
> > stored in a Lua table, in Lua5 this was simplified by allowing access
to
> > that table and using data access metamethods. Local variables,
> >however, are
> > still left unhandled.

True enough. Use setter and accessor functions instead.

> Should I switch to Lua5 now or will porting my code to it later be
> easy.I don't want to mess with beta software unless I have to(there
> aren't debian packages for it either I think) but I don't want to
> rewrite the whole thing again later when lua5 is released.

You will have to rewrite the whole thing, so you should think about it now.
It is very easy to install lua, you do not need a package. Just download
the source tarball, edit the config file if you want readline to work (new
with beta5) and do make ; make install. I think it is pretty stable: the
Lua team's betas are other people's released software, something which I
really appreciate about Lua.

In Lua beta5 there is no longer a settable metamethod, so you have to work
around that. The __newindex metamethod only applies to keys which are not
in the table. One simple workaround is:

do
  local meta, getters, setters = {}, {}, {}
  local old_meta = getmetatable(getglobals())
  local old_index, old_newindex = old_meta.__index, old_meta.__newindex

  -- populate getters and setters somehow, probably by getting them
  -- from your C coce

  -- you might want to change the calls below to object calls,
  -- such as getters[k](getters[k], k)
  -- For efficiency, you probably only want to do that lookup once.

  -- this assumes that the old __index metamethod was functional. It might
be
  -- a table, though... that needs to be checked as well.
  -- And I haven't tried this code, I just typed it.

  meta = {}

  if old_index
    then
      function meta.__index(t, k)
        if getters[k] then return getters[k](k) else return old_index(t, k)
end
      end
    else
      function meta.__index(t, k)
        if getters[k] then return getters[k](k) end
      end
  end

  if old_newindex
    then
      function meta.__newindex(t, k, v)
        if setters[k] then setters[k](k, v) else old_newindex(t, k, v) end
      end
    else
      function meta.__newindex(t, k, v)
        if setters[k] then setters[k](k, v) end
      end
  end

  setmetatable(getglobals(), meta)
end