First off, to whet your curiosity, you should read what both the manual and the book have to say about metatables.
“But why do I have to do that?” Well, the short answer is, the text object needs to find a string (it does display text, after all), and so it expects to get a string. And text
is the delivery mechanism.
As you probably realized, Solar gives you display objects as tables. You can add entries to them and even inspect them with pairs()
(although you should definitely not blindly muck with the stuff that’s already there! ). If you do that, you’ll see a “proxy” value.
There’s a native (C++) component to display objects as well, and these are coupled to the table, i.e. the Lua part, through its metatable, in particular its __index
and __newindex
metamethods.
Minus some glue, the __index
part of text objects begins here and the __newindex
follows that. You can see the case 0
in each of them, with the comments indicating it corresponds to text
.
The upshot is that, since the tables don’t have a text
field, accesses go through the __index
and __newindex
machinery. (You actually could use rawset()
to assign this field, but there will be nothing but confusion and sadness. )
I would probably err on this case being on the “it’s not a good idea” side, but since you’re “Asking more out of curiosity”, you can get something like what you want by writing your own metamethods.
In your __index
, for the text key, if you detected (through some ancillary key, not text itself; my_text, for example), that there was table data, you could return the table’s text member. Otherwise, for this key or any other, just forward on to Solar’s behavior.
In the __newindex
, if you encounter the text key, and it’s table data, save it in that ancillary key AND forward the string on to the built-in behavior. For anything else, just forward it on.
This is a little tricky since you probably don’t want to stomp on Solar’s own metatables—so you want to chain your own to one of those—and you need to make your own __index
and __newindex
do the forwarding.
I have code for this (undocumented, mea maxima culpa)…
…and here is an example of it being used, in this case to augment a circle object. (On first use it will rig everything up, then reuse the new metatable when it sees Warp
again.) I probably have better examples elsewhere, but this shows adding methods and “read properties” at least.