msgpack-ruby icon indicating copy to clipboard operation
msgpack-ruby copied to clipboard

Correct way to pack and unpack `Struct` instances.

Open ioquatix opened this issue 1 year ago • 3 comments

It would be nice to give some examples of how to efficiently pack and unpack Struct instances.

    def make_packer(io)
      packer = MessagePack::Packer.new(io)
      packer.register_type(0x00, Symbol, :to_msgpack_ext)
      packer.register_type(0x01, Time) {|object| object.to_s}
      packer.register_type(0x0F, Coverage::Source) do |object|
        object.to_a.to_msgpack
      end
      
      return packer
    end
    
    def make_unpacker(io)
      unpacker = MessagePack::Unpacker.new(io)
      unpacker.register_type(0x00, Symbol, :from_msgpack_ext)
      unpacker.register_type(0x01, Time, :parse)
      unpacker.register_type(0x0F) do |data|
        Coverage::Source.new(*MessagePack.unpack(data))
      end
      
      return unpacker
    end

This is what I'm doing, but the internal usage of MessagePack.unpack feels a bit wrong.

ioquatix avatar Sep 20 '22 02:09 ioquatix

the internal usage of MessagePack.unpack feels a bit wrong.

Yes it is. You want to use a recursive type: https://github.com/msgpack/msgpack-ruby#extension-types

Also you'd probably save yourself a lot of trouble if you used a Factory pool rather than build the packer and unpacker: https://www.rubydoc.info/gems/msgpack/MessagePack/Factory#pool-instance_method

byroot avatar Sep 20 '22 06:09 byroot

It's not clear from the example what recursive: true does. Does it give the extra packer/unpacker argument? Can you use it on Packer and Unpacker instances?

ioquatix avatar Sep 20 '22 07:09 ioquatix

Does it give the extra packer/unpacker argument?

What extra packer? What argument?

recursive: true allow the extension proc to read or write the stream. So that allow you to serialize your custom types into a combinaison of natively supported types rather than having to pack it yourself into a string.

Can you use it on Packer and Unpacker instances?

Yes, but I heavily recommend to not work with packer and unpacker instances, always use a factory.

byroot avatar Sep 20 '22 07:09 byroot

Okay, that makes perfect sense, and on reading the documentation again I see a good example of Point struct. Thanks!

ioquatix avatar Oct 15 '22 03:10 ioquatix