marshal-md

Human-readable Ruby Marshal alternative. Serialize objects to Markdown with full round-trip fidelity.

101 tests + 108 RSpec examples, 100% passed
gem install marshal-md
Marshal.dump (binary)
\x04\b{\a:\tname\"\nAlice:\bage\x1Ei\x23
MarshalMd.dump (readable)
{name: "Alice", age: 30} (Hash)

Same API. Readable output.

require "marshal-md"

md = MarshalMd.dump(obj)                  # Ruby object  ->  Markdown string
obj = MarshalMd.load(md)                  # Markdown string  ->  Ruby object

MarshalMd.dump(obj, io)                   # write to IO
MarshalMd.dump(obj, 3)                    # depth limit
MarshalMd.load(md, proc)                  # proc callback
MarshalMd.load(md, freeze: true)          # freeze all objects

# Drop-in replacement
require "marshal-md/patch"
Marshal.dump(obj)  # now outputs Markdown
Marshal.load(md)   # auto-detects format

All Ruby types

Integer, Float, String, Symbol, Array, Hash, Range, Regexp, Time, Struct, Complex, Rational, Encoding, Exception, Class, Module, and any custom object.

Circular references

Anchor/reference syntax handles shared objects and circular references, just like Marshal.

Zero dependencies

Pure Ruby. No external gems. Works with Ruby 2.5+.

Subclass support

MyArray < Array, MyTime < Time, etc. Preserves class identity, instance variables, and module extensions.

Full Marshal API

Depth limit, IO/pipe, proc callback, freeze mode, compare_by_identity, safety checks for recursive dump and mutation detection.

Diff-friendly

Scalars have no type annotations. Text output works with git diff, code review, and version control.

Format examples

# Scalars — no type annotations needed
42
"hello"
:foo
true

# Nested objects
#<User> (User)
  @name: "Alice"
  @scores: [85, 92, 78] (Array)
  @address:
    #<Address> (Address)
      @city: "Tokyo"
      @zip: "100-0001"

# Circular reference
&obj_1 (Array)
  1
  2
  *obj_1 (ref)

# Binary data
base64:iVBORw0KGgo... (String, ASCII-8BIT, 4096 bytes)