Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When did equality metamethods change?

Tags:

lua

There seems to be a change in the way equality metamethods are executed, but I cannot find the documentation in any of the 5.1, 5.2 or 5.3 reference manuals (under the Change in the Language sections under Incompatabilities)

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

from (http://lua-users.org/wiki/MetatableEvents) and tested to be true on local 5.1.5 implementation

In Lua 5.3 running this actually yields

true
true

Executing from (https://www.lua.org/demo.html)

Is this a bug? Do metamethods for equality no longer have to be the same reference?

like image 677
James Avatar asked Nov 14 '25 09:11

James


2 Answers

I'm not a Lua expert, but comparing the 5.2 docs:

"eq": 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.

and the 5.3 docs:

__eq: 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.

the 5.3 docs list no requirement that the operands have the same metamethod.

like image 69
user2357112 supports Monica Avatar answered Nov 17 '25 09:11

user2357112 supports Monica


If I'm reading the source code on the Lua website right, this changed between Lua 5.2 and 5.3.

In Lua 5.2, if a pair of tables or userdata are not equal by reference, the equality of the two __eq metamethods was checked in luaV_equalobj_ (using get_equalTM, where TM stands for "tag method", the old name for metamethods), and only then would the metamethod be used. (In 5.1 the process is similar, but the methods are called luaV_equalval and lua_getcompTM.) In 5.3, luaV_equalobj looks for an __eq metamethod in the first operand and then in the second operand; if any metamethod was found, it is called.

There was a discussion about this on the Lua list in 2015: Lua 5.3 changes to .__eq (easier-to-read Nabble version).

like image 37
cyclaminist Avatar answered Nov 17 '25 09:11

cyclaminist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!