lua-users home
lua-l archive

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



On 27-Jun-07, at 6:09 PM, Gavin Kistner wrote:

What do _you_ do when you need a simple, lightweight way to create some
unique values?

I use simple lower case strings, unless a better solution
occurs to me. In your example, I would might use "good", "sin",
"cos" and "sin".

Having said that, I might well choose to use math.sin and math.cos
for the operation, if those were appropriate. For example,
rather than using an enumeration of "BlendType"'s, I would be
tempted to use the actual blending functions.

Do you worry about cross-enumeration comparisons?

No. I figure that it's about the same as using the same name
for two completely unrelated methods in unrelated classes.
(Shape:draw() versus Sheriff:draw() would be the classic example).

Although you didn't ask about C, here's how I bridge with
C enumerations.The validity of the string is checked
by looking up the C enumeration in a table attached as an
upvalue to the C closure, which is reasonably simple and fast:

static int foo_set_op (lua_State *L) {
  lua_Integer op = 0;
  Foo *self = check_self(L);
  if (lua_type(L, 2) == LUA_TSTRING) {
    lua_rawget(L, lua_upvalueindex(1));
    op = lua_tointeger(L, -1);
    if (op != 0 || lua_type(L, -1) == LUA_TNUMBER) {
      self->op = op;
      return 0;
    }
  }
  luaL_typerror(L, 2, "Operation");
  return 0;
}

static int foo_get_op (lua_State *L) {
  Foo *self = check_self(L);
  lua_rawgeti(L, lua_upvalueindex(1), self->op);
  return 1;
}

The same table is used for both functions; it has integer keys
which map to strings, and string keys which map to integers.

check_self, by the way, is implemented by setting the environment
table of the closures to the metatable for the object type, so it
can be quite general:

void *check_self (lua_State *L) {
  if (lua_getmetatable(L, 1) && lua_rawequal(L, -1, LUA_ENVIRONINDEX)) {
    lua_pop(L, 1);
    return lua_touserdata(L, 1);
  }
  else {
    lua_getfield(L, LUA_ENVIRONINDEX, "__typename");
    luaL_typerror(L, 1, lua_tostring(L, -1));
    return 0;
  }
}

The enumeration checking code above can be refactored for convenience
as well.