lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2015-07-12 14:20 GMT+02:00 Peter Aronoff <telemachus@arpinum.org>:

> I'm a little confused abut the changes to .__eq in Lua 5.3. Now that Lua will
> call the first .__eq found if *either* of the two operands to == has a defined
> .__eq method, some odd results seem to follow. In particular, == is now order
> dependent. x == y and y == x can return different results. Is this really
> desirable?
>
> Consider the code below and the results it would yield for Lua 5.3 versus for
> earlier versions of Lua:
>
>     foo, bar = {4}, {4}
>     mt1, mt2 = {}, {}
>     happy = function () return true end
>     sad = function () return false end
>     mt1.__eq = happy
>     mt2.__eq = sad
>
>     print(foo == bar, bar == foo) -- false, false for all versions
>
>     setmetatable(foo, mt1)
>     print(foo == bar, bar == foo) -- false, false or true, true?
>
>     setmetatable(bar, mt2)
>     print(foo == bar, bar == foo) -- false, false or true, false?

The old behaviour required metamethods to be identical.

This disqualifies inheritance situations. I.e. suppose there
is a constructor A=myclass(B) which basically packs the
metatable of A and falls back to B otherwise. Now A==B is
quite a reasonable thing to test for, but it would always be
false under the old behaviour. The asymmetry is the price
you pay for the extra flexibility.

I agree that it is a little counterintuitive and possibly confusing
to newbies, but IMHO programmers who exploit metamethods
declare themselves to be de facto non-newbies.