как расширить метатаблицы lua с помощью (что-то вроде) __index

#lua

#lua

Вопрос:

Следующий сеанс показывает, что я пытался. Должно быть, я где-то неправильно прочитал какую-то документацию, в которой (как мне показалось) говорилось, что элемент __index в метатаблице предоставляет значение по умолчанию, когда таблица не предоставляет элемент для этого ключа. Дело в том, что это не работает с самими метатаблицами, но я понятия не имею, почему нет. Где в документации это объясняется, и что я могу с этим поделать в таких случаях?

Спасибо!

 > a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631ae0
> c = { __tostring = function(x) return "X" end }
> setmetatable(b,{ __index=c })
table: 0000000002631560
>
> print(a)
table: 0000000002631ae0
> -- I was expecting: X
> print(getmetatable(a).__tostring)
function: 0000000002633840
> print(tostring(a))
table: 0000000002631ae0
> -- Again, expecting X
> print(getmetatable(a).__tostring(a))
X
>
  

Вот еще один пример.

 > a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631fe0
> c = { __add = function(x,y) return "X" end }
> setmetatable(b,{ __index=c })
table: 00000000026316a0
>
> print(a a)
stdin:1: attempt to perform arithmetic on a table value (global 'a')
stack traceback:
        stdin:1: in main chunk
        [C]: in ?
>
  

Таким образом, эта проблема не относится к print и tostring . Конечно, в реальных ситуациях я хочу иметь много разных объектов, разделяющих множество метатаблических значений, без необходимости копировать все каждый раз…

Ответ №1:

Это связано __index с операциями индексации, такими как tbl.var . Lua не использует __index для получения других метаметодов (например __tostring ).

Вы используете print который вызывает __tostring непосредственно из метатаблицы, здесь он не используется __index .

__index: таблица операций доступа к индексации [ключ]

Узнайте больше: https://www.lua.org/manual/5.4/manual.html#2.4

Решением было бы объединение метатаблиц c с b .

 setmetatable(b,{ __tostring = c.__tostring })
print(b) -- X
  

Комментарии:

1. Я не знаю, где описан tbl.var. Но это не относится к print и __tostring . Я добавил еще один пример…

2. @SadieKaye Хорошо, немного перефразируя, Lua не использует __index для получения других метаметодов. Это влияет на __tostring, __add, __sub, __mul, __mode, __pairs и т. Д. (Все они)

3. Итак, вопросы.. где это задокументировано и что мне с этим делать?

4. @SadieKaye Это конкретно не задокументировано, но в нем упоминается, когда вызывается __index . lua.org/manual/5.4/manual.html#2.4 > __index: операция доступа к индексации «таблица [ключ]»

5. @SadieKaye: Это задокументировано здесь . «Lua запрашивает метаметоды в метатаблицах, используя необработанный доступ (см. rawget )».