ipairs and metamethods in 5.3

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ipairs and metamethods in 5.3

Pierre Chapuis
Hello list,

I have an issue and I was wondering how you would solve it.

I tried to do something like this:

    local mp = require "MessagePack"
    local pretty = require "pl.pretty"
    pretty.dump(mp)

the Penlight code does something like:

    for _ in ipairs(mp.packers) do end

and it fails with:

    lua: /usr/share/lua/5.3/MessagePack.lua:46: pack '1' is
    unimplemented

because of a metamethod on the `packers` table [1].

How would you keep the feature of raising an error on direct access, but
still make it work with `ipairs`?

If possible, it would not use the debug library, e.g. not something
like:

    if debug.getinfo(2, "n").name == "for iterator"

It would not work anyway since MessagePack sets `_ENV` to `nil`...

In 5.2 it could have used `__ipairs` but it is deprecated now that
`ipairs` honors `index`.

[1]
https://github.com/fperrad/lua-MessagePack/blob/dc12b0175b9dd3a921e2c693cdeb929ac080ed4d/src5.3/MessagePack.lua#L45-L47

--
Pierre Chapuis

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

Dirk Laurie-2
2017-07-27 12:40 GMT+02:00 Pierre Chapuis <[hidden email]>:

> I tried to do something like this:
>
>     local mp = require "MessagePack"
>     local pretty = require "pl.pretty"
>     pretty.dump(mp)
>
> the Penlight code does something like:
>
>     for _ in ipairs(mp.packers) do end
>
> and it fails with:
>
>     lua: /usr/share/lua/5.3/MessagePack.lua:46: pack '1' is
>     unimplemented
>
> because of a metamethod on the `packers` table [1].
>
> How would you keep the feature of raising an error on direct access, but
> still make it work with `ipairs`?

Choose one.

1. Tell the developers of the two modules to get their act together.

2. Modify the copy of Penlight on your machine.

3. Redefine the global 'ipairs' (pl.pretty does not cache it locally)

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

steve donovan
On Thu, Jul 27, 2017 at 2:05 PM, Dirk Laurie <[hidden email]> wrote:
> 1. Tell the developers of the two modules to get their act together.
> 2. Modify the copy of Penlight on your machine.

1 is probably a better solution, because it's going to bite other
people. M. Chapuis, will you open an issue? Otherwise I tend to forget
things ;)

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

Pierre Chapuis
On Thu, Jul 27, 2017, at 15:12, steve donovan wrote:

> 1 is probably a better solution, because it's going to bite other
> people. M. Chapuis, will you open an issue? Otherwise I tend to forget
> things ;)

OK, I thought it was more of a MessagePack issue from my point of view,
but I can open an issue on Penlight as well.

--  
Pierre Chapuis

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

steve donovan
In reply to this post by Dirk Laurie-2
On Thu, Jul 27, 2017 at 2:05 PM, Dirk Laurie <[hidden email]> wrote:
> 3. Redefine the global 'ipairs' (pl.pretty does not cache it locally)

I have mixed feelings about this - on the one hand, it's flexible, and
on the other, it's a recipe for chaos. I know that we are not so
tolerant of monkey patching as the Rubyists!  But the problem here is
more of consistency, because I _do_ cache common calls in most other
places. A reasonably elegant compromise is to always cache, and
therefore modification must take place before any PL module is loaded.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

Hisham
In reply to this post by Pierre Chapuis
On 27 July 2017 at 07:40, Pierre Chapuis <[hidden email]> wrote:

> Hello list,
>
> I have an issue and I was wondering how you would solve it.
>
> I tried to do something like this:
>
>     local mp = require "MessagePack"
>     local pretty = require "pl.pretty"
>     pretty.dump(mp)
>
> the Penlight code does something like:
>
>     for _ in ipairs(mp.packers) do end
>
> and it fails with:
>
>     lua: /usr/share/lua/5.3/MessagePack.lua:46: pack '1' is
>     unimplemented
>
> because of a metamethod on the `packers` table [1].
>
> How would you keep the feature of raising an error on direct access, but
> still make it work with `ipairs`?
>
> If possible, it would not use the debug library, e.g. not something
> like:
>
>     if debug.getinfo(2, "n").name == "for iterator"
>
> It would not work anyway since MessagePack sets `_ENV` to `nil`...
>
> In 5.2 it could have used `__ipairs` but it is deprecated now that
> `ipairs` honors `index`.

On the Penlight side, it would probably be a good to protect the
indexing of this generic traversal with pcall.

On the MessagePack side, if a `packer` called 1 does not make sense,
I'd add an extra `if k == 1 then return nil end` just to appease
ipairs.

-- Hisham

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ipairs and metamethods in 5.3

Pierre Chapuis
> On the MessagePack side, if a `packer` called 1 does not make sense,
> I'd add an extra `if k == 1 then return nil end` just to appease
> ipairs.

I didn't think about this, it makes a lot of sense.

--
Pierre Chapuis

Loading...