lua-users home
lua-l archive

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

Peter Odding wrote:
Hi all! I'm (still) working on binding APR. Currently busy with pipes, which seem to be backwards compatible with files but not the other way around:

 * pipes have a timeout which needs two methods (timeout_get/timeout_set)
* I need to make sure I'm dealing with a pipe (instead of a file) when using them as stdin/stdout/stderr for processes

Right now my io_file module uses luaL_checkudata(L, i, "apr-file") to validate arguments. Of course when I give pipes their own metatable my io_file module will start rejecting pipes, which is not my intention.

One solution is a function in the vein of luaL_checkudata that checks a userdata argument for one *of a given set* of metatable names, like luaL_checkudata_m(L, i, "apr-file", "apr-pipe"). Have any of you needed this functionality before? Have you used a different approach?

In fact, there is a mechanism like this in LuaSocket, which you might
want to look at.

My approach is a bit different, though: I prefer to put the metatable
itself where object methods can get at it, generally as upvalue 1. This
allows checking against the metatable of the target object with a simple
equality test. I also make sure that the environment table of object
methods is the method table for the object.

With that setup, it's easy to handle polymorphism. The key, as it were,
is to use tables as keys. For example, each metatable can contain
interface method tables as keys (mapped to the value true, for example.)
Alternatively, or simultaneously, a metatable can hold superclass metatables as keys. Either of these allows a method to verify membership
rapidly by looking up its own metatable (upvalue 1) or method table
(environment table) as a key in the metatable of the target object.

It's easier to draw this on paper than describe it, but I hope that
helps a bit.