Кажется, есть изменения в способе выполнения метаметодов равенства, но я не могу найти документацию ни в одном из 5.1, 5.2 или 5.3 справочные руководства (в разделах «Изменение языка» раздела «Несовместимость»)

t1a = {}
t1b = {}
t2  = {}
mt1 = { __eq = function( o1, o2 ) return 'whee' end }
mt2 = { __eq = function( o1, o2 ) return 'whee' end }

setmetatable( t1a, mt1 )
setmetatable( t1b, mt1 )
setmetatable( t2,  mt2 )

print( t1a == t1b )     --> true
print( t1a == t2 )      --> false

Из (http://lua-users.org/wiki/MetatableEvents) и протестированы на true для локальной реализации 5.1.5

В Lua 5.3 это фактически дает

true
true

Выполнение из (https://www.lua.org/demo.html)

Это ошибка? Разве метаметоды равенства больше не должны быть одной и той же ссылкой?

lua
3
James 13 Мар 2018 в 05:18

2 ответа

Лучший ответ

Я не эксперт по Lua, но сравниваю документы 5.2:

"eq": операция ==. Функция getequalhandler определяет, как Lua выбирает метаметод для равенства. Метаметод выбирается только тогда, когда оба сравниваемых значения имеют один и тот же тип и один и тот же метаметод для выбранной операции, а значения являются либо таблицами, либо полными пользовательскими данными.

И 5.3 документы:

__eq: операция равенства (==). Поведение аналогично операции сложения, за исключением того, что Lua будет пробовать метаметод только тогда, когда сравниваемые значения являются либо обеими таблицами, либо обоими полными пользовательскими данными, и они примитивно не равны. Результат вызова всегда преобразуется в логическое значение.

В документации 5.3 не требуется, чтобы операнды имели один и тот же метаметод.

3
user2357112 supports Monica 13 Мар 2018 в 02:28

Если я правильно читаю исходный код на веб-сайте Lua, это изменилось между Lua 5.2 и 5.3.

В Lua 5.2, если пара таблиц или пользовательских данных не равны по ссылке, равенство двух метаметодов __eq проверялось в luaV_equalobj_ (с использованием get_equalTM, где TM означает" метод тега ", старое название метаметодов), и только тогда будет использоваться метаметод. (В 5.1 процесс аналогичен, но методы называются {{X3 }} и lua_getcompTM.) В версии 5.3 luaV_equalobj ищет метаметод __eq в первом операнде, а затем во втором операнде; если какой-либо метаметод был найден, он вызывается.

В 2015 году в списке Lua обсуждалась эта тема: < em> Lua 5.3 меняется на .__ eq (более удобная для чтения версия Nabble).

0
cyclaminist 13 Мар 2018 в 23:12