lua-users home
lua-l archive

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


Zitat von Ben <thebassplayer@gmail.com>:

> I'm of the opinion of that if you have an already working, simple
> solution, why bother with another?  

True.

> Of course, others might have ideas
> of how a userdata might be better, but I certainly can't think of a
> good reason.

I have one: You can overload the index/newindex operator and make the userdata
act like a table. I have found this extremely useful in many cases. For
example, assume you have a matrix class and a list of matrix userdata objects
and calculate some special values for each matrix. 

list = { ... a list of matrices ... }

for i,matrix in ipairs(list) do
  local someinformation = matrix:calculatesomething()
  ... further stuff ...
  matrix.specialvalue = someinformation
end

-- all matrices in list have now a specialvalue field
----

Before I implemented my userdata this way, I stored such information in extra
lookup tables and so on. I can't express how useful this implementation was for
me. Especially if the userdata values are put in some C data structures (like
spaces for collision detection etc.) and getting then that userdatas (of
colliding objects) in return. If I can put in additional information in that
userdata I don't have to use other techniques to retrieve that information.

The userdata needs only to overload the __newindex and __index metatable and
store new key/values in a table inside the metatable of the userdata OR (if the
userdata shouldn't have unique metatables) store the value in a table of the
registry where the key values are the userdata values and it's a __mode='k'
table, so it's weak. 

Iterating the userdata with next/ipairs/pairs won't be possible unless further
steps are taken, but unlike the storing of additional information, I never
found that this was required for me at any point. If I needed that, I would put
a special key in the table of the userdata with a selfreference (like
__selftable).


Eike


> 
> If you're thinking indirection, a closure has the function call, yes,
> but userdata has a tag lookup + function call.  A closure is looking
> more and more the best solution to me.
> 
> Cheers,
> Ben
> 
> On Dec 13, 2007 6:28 PM, Eric Tetz <erictetz@gmail.com> wrote:
> > I've got a library that returns a callable object:
> >
> >   foo = import("some", "configuration", "parameters", "here")
> >   ...
> >   foo("user", "args", "here")
> >
> > There are no C resources associated with 'foo' that need to be
> > allocated/released, and the only thing a user can do with this object
> > is call it, so I can just as easily implement 'foo' as a C closure or
> > as userdata with a __call metamethod. Is there a reason to prefer one
> > approach over the other?
> >
> > Currently I'm using a closure because it seems simpler. The sample
> > code I looked at for doing it with metatables seemed a lot more
> > complicated.
> >
> > Thanks,
> > Eric
> >
>