syntaxluaoverridinglua-tablemeta-method

Can I override a Lua table's return value for itself?


Is it possible for a table, when referenced without a key, to return a particular value rather than a reference to itself?

Let's say I have the following table:

local person = {
    name  = "Kapulani",
    level = 100,
    age   = 30,
}

In Lua, I can quite easily refer to "person.name", "person.level", or "person.age" and get the values as expected. However, I have certain cases where I may want to just reference "person" and, instead of getting "table: " I'd like to return the value of "person.name" instead.

In other words, I'd like person.x (or person[x]) to return the appropriate entry from the table, but person without a key to return the value of person.name (or person["name"]). Is there a mechanism for this that I haven't been able to find?

I have had no success with metatables, since __index will only apply to cases where the key does not exist. If I put "person" into a separate table, I can come up with:

local true_person = {
    ... -- as above
}

local env_mt = {
    __index = function(t, k)
        if k == 'person' then
            return true_person
        end
    end
}

local env = setmetatable( {}, env_mt )

This lets me use __index to do some special handling, except there's no discernable way for me to tell, from __index(), whether I'm getting a request for env.person (where I'd want to return true_person.name) or env.person[key] (where I'd want to return true_person as a table, so that 'key' can be accessed appropriately).

Any thoughts? I can approach this differently, but hoping I can approach this along these lines.


Solution

  • You can do it when the table is being used as a string by setting the __tostring metatable entry:

    $ cat st.lua
    local person = {
        name  = "Kapulani",
        level = 100,
        age   = 30,
    }
    
    print(person)
    print(person.name)
    print(person.age)
    
    setmetatable(person, {__tostring = function(t) return t.name end})
    print(person)
    
    $ lua st.lua
    lua st.lua
    table: 0x1e8478e0
    Kapulani
    30
    Kapulani