lua-users home
lua-l archive

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

> The example below introduced me to the newproxy() method. Unless I am 
> mistaken, in the example below, the use of newproxy() is crucial because 
> otherwise the type of the returned "u" variable will be "table", and 
> setting __len on the metatable of a table does not change the behavior 
> of the # operator.


> However, according to old newsgroup postings, newproxy() is an 
> unsupported method. Is there another way to create a userdata object 
> without using C code?

No, and newproxy is undocumented and unsupported. The motivation is given by

"This is a very experimental feature. We wanted a simple and secure way
of creating userdata in Lua. It has several uses, such as to monitor
garbage collection, as a light "unique" object, and for testing ;-).
But we cannot allow Lua to change the metatable of those userdata;
otherwise, Lua could break other libraries (e.g. give one of these
userdata as a file to be closed). To allow each userdata to have its own
new metatable or to share the metatable of another such userdata seems
flexible and secure."

Rici Lake also offers some motivation and a reason for the function name:

"But the basic idea is simple enough: Sometimes all you need is a metatable;
creating a whole empty table to attach the metatable to is a bit wasteful.
Creating a zero-length userdata is cheaper, and you can attach a metatable
to it, but the standard interface doesn't allow Lua programs to either
create userdata or manipulate userdata metatables.

Solution: write a little C function which creates a zero-length full
userdata with a specific metatable. The function is, I believe, called

Besides being cheaper, using userdata as proxies has the advantage over tables
of allowing __len metamethods, as you have already noticed. As other examples,
userdatum proxies can be used in and instead of empty tables. For the latter:

function readonly(t)
  local u = newproxy(true)
  local mt = getmetatable(u)
  mt.__index = t
  mt.__newindex = function()
    error("attempt to update a read-only table", 2)
  -- can't get this with table proxies:
  mt.__len = function() return #t end
  return u


A mathematician is a device for turning coffee into theorems.
        -- P. Erdos 

Luis Carvalho
Applied Math PhD Student - Brown University
PGP Key: E820854A <>