lua-users home
lua-l archive

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

It was thus said that the Great Jasper Klein once stated:
> Hello,
> For a C-module [1] I've wrapped enums in an userdata with a metatable that 
> implements the binary operators.
> This works fine but has two downsides.
> For example when checking if a permission is set;
> if variable_with_permissions & ~perms.owner_write == perms.owner_write then
>        -- ...
> end
> 1) The '== perms.owner_write' part is required because an if-statement 
> evaluates uservalues as true.
>      '__eq' metamethod is only called when both operands are a table or 
>      userdata.
> 2) The '&' and '~' operators create a new uservalues that are immediately 
> garbage.
> Are these downsides really an issue?

  Only if the program isn't running fast enough.  If no one complains, then
it isn't an issue.

> How would you expose enum members (not the values) from the C-API to Lua 
> that are used as flags which can be combined?

  I've solved this several ways.  At work, we have a data file that contains
a 32-bit value that defines a bunch of flags.  In the Lua module, I
break this field out to individial boolean values:

	licensed = true,
	mdn      = true,
	min      = false,
	capable  = true,
	company  = false,
	trace    = true,
	-- ...

  The original module was written when Lua 5.1 was the latest version, which
is why I did it this way (no bit module, no bit operations).  It hasn't been
a performance issue for us (we use this code to handle actual phone calls
being made for the Oligarchic Cell Phone company).  If you go this way, then
your code above could be:

	if variable_with_permissions.owner_write then
	  -- ...

  Does it need to do that exactly?  Not really---I could see having a
userdata with a custom __index method that does the & operator in C.  

  Another way I've done this, for file system code in particular [2], was to
return the permissions as a string:

	perms = "---rw-r--r--"

following the output from ls (more or less).  So the owner permissions are
in the second group of three characters ('rw-').  

	if variable_with_permissions.perms:match("^....w") then
	  -- ...

  Maybe not the clearest code, but it could also work.


> [1]

[2]	I wrote my own POSIX wrapper: