Purpose
This tutorial shows how to create custom extension types for serializing objects that don’t have native MessagePack support.
References
-
Extension types - Extension type concepts
-
Extension types reference - Detailed documentation
Prerequisites
-
Completed Getting started tutorial
Understanding extension types
MessagePack defines a set of built-in types (nil, boolean, integer, float, string, array, map). For custom Ruby classes, you need to register an extension type.
An extension type requires:
-
A type ID (-128 to 127)
-
A packing method that converts your object to binary
-
An unpacking method that reconstructs your object from binary
Simple example: Point class
Define the class
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def to_msgpack_ext
# Pack as two 32-bit integers
[@x, @y].pack("ll")
end
def self.from_msgpack_ext(data)
x, y = data.unpack("ll")
new(x, y)
end
def to_s
"(#{@x}, #{@y})"
end
endComplex example: Nested objects
Define a container class
class TreeNode
attr_reader :value, :left, :right
def initialize(value, left = nil, right = nil)
@value = value
@left = left
@right = right
end
def to_msgpack_ext(packer)
# Serialize as hash with recursive packing
packer.write({
value: @value,
left: @left,
right: @right
})
end
def self.from_msgpack_ext(unpacker)
# Recursively deserialize
data = unpacker.read
new(
data[:value],
data[:left],
data[:right]
)
end
endUsing procs for simple types
For simple classes, you can use procs directly:
require 'uri'
factory = Messagepack::Factory.new
factory.register_type(0x10, URI,
packer: ->(uri) { uri.to_s },
unpacker: ->(str) { URI.parse(str) }
)
uri = URI.parse("https://example.com")
binary = factory.pack(uri)
result = factory.unpack(binary)
# => #<URI::HTTPS https://example.com>Next steps
-
Thread-safe usage - Use factories in multi-threaded applications
-
IO streaming - Work with streams and networks