From: Serge Petrenko via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: "Бабин Олег" <olegrok@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v2 1/2] lua: introduce table.equals method
Date: Mon, 16 Aug 2021 19:47:07 +0300 [thread overview]
Message-ID: <ede6b3d1-2639-66c1-ccde-c31ba1f49762@tarantool.org> (raw)
In-Reply-To: <1629128500.838902794@f338.i.mail.ru>
16.08.2021 18:41, Бабин Олег пишет:
> Ok. Thanks for your changes. Don’t forget to changelog entry and
> docbot request and LGTM then.
>
Thanks for your answers!
Yep, sure. Done.
> Понедельник, 16 августа 2021, 18:36 +03:00 от Serge Petrenko
> <sergepetrenko@tarantool.org>:
>
>
> 16.08.2021 16:03, Бабин Олег пишет:
> > Thanks for your fixes.
> >
> > Понедельник, 16 августа 2021, 10:53 +03:00 от Serge Petrenko
> > <sergepetrenko@tarantool.org
> </compose?To=sergepetrenko@tarantool.org>>:
> >
> > Thanks for a thorough review!
> >
> > I've force pushed the following fixes:
> >
> > =============================================
> >
> > diff --git a/src/lua/table.lua b/src/lua/table.lua
> > index 3d5e69e97..edd60d1be 100644
> > --- a/src/lua/table.lua
> > +++ b/src/lua/table.lua
> > @@ -65,8 +65,11 @@ local function table_equals(a, b)
> > if type(a) ~= 'table' or type(b) ~= 'table' then
> > return type(a) == type(b) and a == b
> > end
> > - local mt = getmetatable(a)
> > - if mt and mt.__eq then
> > + local mta = getmetatable(a)
> > + local mtb = getmetatable(b)
> > + -- Let Lua decide what should happen when at least one of the
> > tables has a
> > + -- metatable.
> > + if mta and mta.__eq or mtb and mtb.__eq then
> >
> > I’m not sure that it’s correct. I’ve added a reference to SO
> >
> (https://stackoverflow.com/questions/61946190/lua-eq-on-tables-with-different-metatables
> <https://stackoverflow.com/questions/61946190/lua-eq-on-tables-with-different-metatables>
> >
> <https://stackoverflow.com/questions/61946190/lua-eq-on-tables-with-different-metatables
> <https://stackoverflow.com/questions/61946190/lua-eq-on-tables-with-different-metatables>>)
> > and it seems condition should be following
> > mta and mta.__eq and mta == mtb. Otherwise tables have different
> __eq
> > metamathods and you should compare their content.
> > I’m not sure that my proposal is completely correct and suggest
> to ask
> > Igor about it.
>
> Actually the question you refer to describes Lua 5.3, while LuaJIT
> supports Lua 5.1
> The rules for Lua 5.1 are as follows (taken from
> https://www.lua.org/manual/5.1/manual.html#2.4
> <https://www.lua.org/manual/5.1/manual.html#2.4>):
>
> Use the __eq metamethod only when both objects have the same one.
>
> So, in my case, if at least one metamethod is defined, try to use
> comparison operator.
> If both tables have the same __eq metamethod, Lua will call it.
> If the tables don't share the same metamethod, they will be
> compared like
> Lua does usually: by reference. The result will be false then.
>
>
> I've added one more test though, just in case:
>
> diff --git a/test/app-tap/table.test.lua b/test/app-tap/table.test.lua
> index c7a075aba..ae6fdfa2d 100755
> --- a/test/app-tap/table.test.lua
> +++ b/test/app-tap/table.test.lua
> @@ -8,7 +8,7 @@ yaml.cfg{
> encode_invalid_as_nil = true,
> }
> local test = require('tap').test('table')
> -test:plan(43)
> +test:plan(44)
>
> do -- check basic table.copy (deepcopy)
> local example_table = {
> @@ -258,12 +258,15 @@ do -- check table.equals
> __eq = function(a, b) -- luacheck: no unused args
> return true
> end}
> - local tbl_d = setmetatable({a=15}, mt)
> - local tbl_e = setmetatable({b=2, c=3}, mt)
> + local tbl_d = setmetatable({a = 15}, mt)
> + local tbl_e = setmetatable({b = 2, c = 3}, mt)
> test:ok(table.equals(tbl_d, tbl_e), "table.equals respects
> __eq")
> - test:is(table.equals(tbl_d, {a=15}), false,
> + test:is(table.equals(tbl_d, {a = 15}), false,
> "table.equals when metatables don't match")
> - test:is(table.equals({a=15}, tbl_d), false,
> + test:is(table.equals({a = 15}, tbl_d), false,
> + "table.equals when metatables don't match")
> + local tbl_f = setmetatable({a = 15}, {__eq = function()
> return true
> end})
> + test:is(table.equals(tbl_d, tbl_f), false,
> "table.equals when metatables don't match")
> end
>
>
>
>
> > return a == b
> > end
> > for k, v in pairs(a) do
> > diff --git a/test/app-tap/table.test.lua
> b/test/app-tap/table.test.lua
> > index ec81593f3..029b923fb 100755
> > --- a/test/app-tap/table.test.lua
> > +++ b/test/app-tap/table.test.lua
> > @@ -8,7 +8,7 @@ yaml.cfg{
> > encode_invalid_as_nil = true,
> > }
> > local test = require('tap').test('table')
> > -test:plan(40)
> > +test:plan(43)
> >
> > do -- check basic table.copy (deepcopy)
> > local example_table = {
> > @@ -254,6 +254,14 @@ do -- check table.equals
> > test:ok(table.equals(tbl_a, tbl_c),
> > "table.equals for shallow copied tables after
> > modification")
> > test:is(table.equals(tbl_a, tbl_b), false, "table.equals
> does a
> > deep check")
> > + local mt = {__eq = function(a, b) return true end}
> > + local tbl_d = setmetatable({a=15}, mt)
> > + local tbl_e = setmetatable({b=2, c=3}, mt)
> > + test:ok(table.equals(tbl_d, tbl_e), "table.equals respects
> __eq")
> > + test:is(table.equals(tbl_d, {a=15}), false,
> > + "table.equals when metatables don't match")
> > + test:is(table.equals({a=15}, tbl_d), false,
> > + "table.equals when metatables don't match")
> > end
> >
> > os.exit(test:check() == true and 0 or 1)
> >
> > =============================================
> >
> > >
> > > On 13.08.2021 13:22, Serge Petrenko wrote:
> > >>
> > >>
> > >> 13.08.2021 08:30, Oleg Babin пишет:
> > >>> Thanks for your patch.
> > >>>
> > >>>
> > >>> It seems it works in quite strange way:
> > >>>
> > >>> ```
> > >>>
> > >>> tarantool> table.equals({a = box.NULL}, {})
> > >>> ---
> > >>> - true
> > >>> ...
> > >>>
> > >>> tarantool> table.equals({}, {a = box.NULL})
> > >>> ---
> > >>> - false
> > >>> ...
> > >>>
> > >>> ```
> > >>>
> > >>>
> > >>> I can change arguments order to get different result. Expected
> > false
> > >>> in both cases.
> > >>>
> > >>> For tap it was considered as buggy behaviour
> > >>> https://github.com/tarantool/tarantool/issues/4125
> <https://github.com/tarantool/tarantool/issues/4125>
> > <https://github.com/tarantool/tarantool/issues/4125
> <https://github.com/tarantool/tarantool/issues/4125>>
> > >>>
> > >>>
> > >>
> > >> ====================================
> > >>
> > >> Good catch! Thanks!
> > >>
> > >> Check out the diff:
> > >>
> > >> diff --git a/src/lua/table.lua b/src/lua/table.lua
> > >> index 5f35a30f6..3d5e69e97 100644
> > >> --- a/src/lua/table.lua
> > >> +++ b/src/lua/table.lua
> > >> @@ -63,7 +63,7 @@ end
> > >> -- @return true when the two tables are equal (false otherwise).
> > >> local function table_equals(a, b)
> > >> if type(a) ~= 'table' or type(b) ~= 'table' then
> > >> - return a == b
> > >> + return type(a) == type(b) and a == b
> > >> end
> > >> local mt = getmetatable(a)
> > >> if mt and mt.__eq then
> > >> diff --git a/test/app-tap/table.test.lua
> > b/test/app-tap/table.test.lua
> > >> index a3c9aa123..ec81593f3 100755
> > >> --- a/test/app-tap/table.test.lua
> > >> +++ b/test/app-tap/table.test.lua
> > >> @@ -8,7 +8,7 @@ yaml.cfg{
> > >> encode_invalid_as_nil = true,
> > >> }
> > >> local test = require('tap').test('table')
> > >> -test:plan(38)
> > >> +test:plan(40)
> > >>
> > >> do -- check basic table.copy (deepcopy)
> > >> local example_table = {
> > >> @@ -227,6 +227,10 @@ do -- check table.equals
> > >> test:ok(table.equals({}, {}), "table.equals for empty
> tables")
> > >> test:is(table.equals({}, {1}), false, "table.equals with one
> > >> empty table")
> > >> test:is(table.equals({1}, {}), false, "table.equals with one
> > >> empty table")
> > >> + test:is(table.equals({key = box.NULL}, {key = nil}), false,
> > >> + "table.equals for box.NULL and nil")
> > >> + test:is(table.equals({key = nil}, {key = box.NULL}), false,
> > >> + "table.equals for box.NULL and nil")
> > >> local tbl_a = {
> > >> first = {
> > >> 1,
> > >>
> > >> ====================================
> > >>> On 13.08.2021 02:30, Serge Petrenko via Tarantool-patches wrote:
> > >>>> Introduce table.equals for comparing tables.
> > >>>> The method respects __eq metamethod, if provided.
> > >>>>
> > >>>> Needed-for #5894
> > >>>> ---
> > >>>>
> > >>
> >
> > --
> > Serge Petrenko
> >
> > --
> > Oleg Babin
>
> --
> Serge Petrenko
>
> --
> Oleg Babin
--
Serge Petrenko
next prev parent reply other threads:[~2021-08-16 16:47 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-12 23:30 [Tarantool-patches] [PATCH v2 0/2] allow upgrading from version 1.6 Serge Petrenko via Tarantool-patches
2021-08-12 23:30 ` [Tarantool-patches] [PATCH v2 1/2] lua: introduce table.equals method Serge Petrenko via Tarantool-patches
2021-08-13 5:30 ` Oleg Babin via Tarantool-patches
2021-08-13 10:22 ` Serge Petrenko via Tarantool-patches
2021-08-13 20:13 ` Oleg Babin via Tarantool-patches
2021-08-16 7:53 ` Serge Petrenko via Tarantool-patches
2021-08-16 13:03 ` Бабин Олег via Tarantool-patches
2021-08-16 15:36 ` Serge Petrenko via Tarantool-patches
2021-08-16 15:41 ` Бабин Олег via Tarantool-patches
2021-08-16 16:47 ` Serge Petrenko via Tarantool-patches [this message]
2021-08-13 11:41 ` Vladimir Davydov via Tarantool-patches
2021-08-12 23:30 ` [Tarantool-patches] [PATCH v2 2/2] box: allow upgrading from version 1.6 Serge Petrenko via Tarantool-patches
2021-08-13 11:40 ` Vladimir Davydov via Tarantool-patches
2021-08-16 13:18 ` Бабин Олег via Tarantool-patches
2021-08-16 16:32 ` Serge Petrenko via Tarantool-patches
2021-08-16 18:22 ` Бабин Олег via Tarantool-patches
2021-08-14 8:12 ` [Tarantool-patches] [PATCH v2 0/2] " Vitaliia Ioffe via Tarantool-patches
2021-08-17 7:28 ` Kirill Yukhin via Tarantool-patches
2021-08-17 8:05 ` Kirill Yukhin via Tarantool-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ede6b3d1-2639-66c1-ccde-c31ba1f49762@tarantool.org \
--to=tarantool-patches@dev.tarantool.org \
--cc=olegrok@tarantool.org \
--cc=sergepetrenko@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH v2 1/2] lua: introduce table.equals method' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox