Lua __eq 在具有不同元表的表上
Lua __eq on tables with different metatables
我在本网站 http://lua-users.org/wiki/MetamethodsTutorial 上找到了以下引述:
__eq is called when the == operator is used on two tables, the reference equality check failed, and both tables have the same __eq metamethod (!).
现在我用 Lua 5.3.5 测试了它,这根本不是我观察到的:
a = {}
b = {}
m = {}
m2 = {}
setmetatable(a, m)
setmetatable(b, m2)
m.__eq = function(p1, p2) print("why"); return true end
m2.__eq = function(p1, p2) print("why2"); return true end
这是我测试过的代码。
> a == b
why
true
> b == a
why2
true
它看起来与比较运算符做同样的事情,只是取左边的 table 并使用它的元方法。
这是否在最近的 Lua 版本中发生了变化,还是我的测试有误?
感谢您的帮助。
在 Lua 5.3 中发生了变化。 The readme says it introduced "more flexible rules for some metamethods". Compare the Lua 5.2 reference manual:
the ==
operation. The function getequalhandler
defines how Lua chooses a metamethod for equality. A metamethod is selected only when both values being compared have the same type and the same metamethod for the selected operation, and the values are either tables or full userdata.
function getequalhandler (op1, op2)
if type(op1) ~= type(op2) or
(type(op1) ~= "table" and type(op1) ~= "userdata") then
return nil -- different values
end
local mm1 = metatable(op1).__eq
local mm2 = metatable(op2).__eq
if mm1 == mm2 then return mm1 else return nil end
end
The "eq" event is defined as follows:
function eq_event (op1, op2)
if op1 == op2 then -- primitive equal?
return true -- values are equal
end
-- try metamethod
local h = getequalhandler(op1, op2)
if h then
return not not h(op1, op2)
else
return false
end
end
Note that the result is always a boolean.
与the Lua 5.3 reference manual:
the equal (==
) operation. Behavior similar to the addition operation, except that Lua will try a metamethod only when the values being compared are either both tables or both full userdata and they are not primitively equal. The result of the call is always converted to a boolean.
我在本网站 http://lua-users.org/wiki/MetamethodsTutorial 上找到了以下引述:
__eq is called when the == operator is used on two tables, the reference equality check failed, and both tables have the same __eq metamethod (!).
现在我用 Lua 5.3.5 测试了它,这根本不是我观察到的:
a = {}
b = {}
m = {}
m2 = {}
setmetatable(a, m)
setmetatable(b, m2)
m.__eq = function(p1, p2) print("why"); return true end
m2.__eq = function(p1, p2) print("why2"); return true end
这是我测试过的代码。
> a == b
why
true
> b == a
why2
true
它看起来与比较运算符做同样的事情,只是取左边的 table 并使用它的元方法。
这是否在最近的 Lua 版本中发生了变化,还是我的测试有误?
感谢您的帮助。
在 Lua 5.3 中发生了变化。 The readme says it introduced "more flexible rules for some metamethods". Compare the Lua 5.2 reference manual:
the
==
operation. The functiongetequalhandler
defines how Lua chooses a metamethod for equality. A metamethod is selected only when both values being compared have the same type and the same metamethod for the selected operation, and the values are either tables or full userdata.function getequalhandler (op1, op2) if type(op1) ~= type(op2) or (type(op1) ~= "table" and type(op1) ~= "userdata") then return nil -- different values end local mm1 = metatable(op1).__eq local mm2 = metatable(op2).__eq if mm1 == mm2 then return mm1 else return nil end end
The "eq" event is defined as follows:
function eq_event (op1, op2) if op1 == op2 then -- primitive equal? return true -- values are equal end -- try metamethod local h = getequalhandler(op1, op2) if h then return not not h(op1, op2) else return false end end
Note that the result is always a boolean.
与the Lua 5.3 reference manual:
the equal (
==
) operation. Behavior similar to the addition operation, except that Lua will try a metamethod only when the values being compared are either both tables or both full userdata and they are not primitively equal. The result of the call is always converted to a boolean.