lua-users home
lua-l archive

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


2011/12/15 Ezequiel García <elezegarcia@yahoo.com.ar>:
> Hi!
> I am working on a Lua binding for a library that makes extensive use
> of enums to pass on flags, capabilities, and such. Like this:

A common lua idiom is to represent flags as strings, there is even lua
api support for this: luaL_checkoption().

It works best for a single flag, where you don't have to combine them.

If they have to be combined, but there is only one flag argument to an
API, I like to take a variable length argument list, like:

  do_something(..stuff, "frontonly", "backvideo")

You can see both styles in:

https://github.com/sam-github/netfilter-lua/blob/master/nfct.c

There is an example of a single flag (see line 786) and an example of
multiple flags (see line 388 - but notice that
it is slightly complicated because the string values get mapped to
flags differently depending on another
argument, the subsystem).

Another way for possibly-multiple flags is to allow people to pass
either a single string (when there is one flag), or if the arg
is of table type, to iterate from 1 to #t, and or together all the flags found:

do_something(...stuff, "frontonly")
do_something(...stuff, {"frontonly","backvideo"})

I'd say creating global variables, and forcing people to add them
together (add is same as bitwise or, if the values are
flags) would be my last resort, because it forces me to create module
variables, and for people to access them as module variables. Its not
terrible,
but I've never done it, I like the luaL_checkopt() based approaches.
If they pass in numeric values, you definitely have the problem that
they can
pass in values for bits that don't exist, or shouldn't be set. You can
do this with C enums, too, of course, but the compiler will whine if
you pass non-enum variables to an arg declared as an enum, whereas
with this numeric approach unless you implement a bunch of checking,
undefined values will pass
to your C code.

local o = your_mod.END_OPTS
do_something(....stuff, o.frontonly+o.backvideo)

Cheers,
Sam