2

Is it possible to push a function as a property in Lua?

Right now, I can have Get/Set functions by pushing them as fields like so:

lua_pushcfunction(L,L_Getter);
lua_setfield(L, -2, "GetValue");    

lua_pushcfunction(L,L_Setter);
lua_setfield(L, -2, "SetValue");    

And calling them in Lua like so:

MyObject:SetValue("NewValue")

Is it possible to push a property that's mapped to a C function without metatables? I could map __index and __newindex in metatable to a custom function but I was wondering if there is an easier way. Ultimately, I want the following syntax without metatables:

MyObject.CValue = 1
print(MyObject.CValue)

Is this possible without __index and __newindex?

greatwolf
  • 20,287
  • 13
  • 71
  • 105
Grapes
  • 2,473
  • 3
  • 26
  • 42
  • Have you tried it? It should just work. Provided `MyObject` is a table. – lhf Oct 10 '13 at 21:17
  • @lhf Yep, it just returns `function: 00XXXXXX` which makes sense since that field is mapped to a function. – Grapes Oct 10 '13 at 21:21
  • @lhf It's a table with a metatable that points `__index` to various fields of a userdata. – Grapes Oct 10 '13 at 21:25

1 Answers1

3

Without metatables? No. Metamethods are the only way to invoke a function to evaluate tbl.foo. You could make MyObject a userdata, but again you need a metatable to provide the __index metamethod.

Learn to love metatables. They are the backbone of C/Lua integration.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • I already have a working version of the code with metatables but I was just wondering if I am missing something basic. Apparently not, thanks! – Grapes Oct 10 '13 at 21:31
  • One note: It's easier to implement your `__index`/`__newindex` metamethods in Lua and have them call the corresponding C getters/setters, than to make the metamethods themselves in C. If you do implement `__index`/`__newindex` in C, grab references to all the strings you expect, so that you can match by object identity rather than string comparison. – Sneftel Oct 10 '13 at 21:34
  • interesting, how would you grab the references? And where can I get more information regarding object identity? – Grapes Oct 10 '13 at 21:38
  • 1
    Push the string, use `luaL_ref` to make the reference and `luaL_getref` to access it. Or (actually, this is cleaner) make them upvalues for your C function (see the manual on `lua_pushcclosure` for more details on how to do this) and use `lua_upvalueindex` to find them from your function. In either case, simply use `lua_compare` to see whether it matches. Another approach is to have a table matching fields to getter/setter functions; this might be faster if you have a ton of them. – Sneftel Oct 10 '13 at 21:43