Skip to content

go-ruby-format/format

Repository files navigation

go-ruby-format/format

format — go-ruby-format

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of Ruby's format-string engine — the computation behind Kernel#sprintf, Kernel#format, and String#% — matching MRI (CRuby) 4.0 byte-for-byte across every conversion, flag, width/precision form, named/numbered reference, and the exact ArgumentError / KeyError / TypeError messages.

It is the formatting backend for go-embedded-ruby, but is a standalone, reusable module with no dependency on the Ruby runtime — mirroring go-ruby-regexp (Onigmo) and go-ruby-erb (ERB).

Install

go get github.com/go-ruby-format/format

Usage

package main

import (
	"fmt"
	"math/big"

	"github.com/go-ruby-format/format"
)

func main() {
	// Plain Go values: int, int64, *big.Int, float64, string, bool, nil,
	// []any, format.Symbol.
	out, _ := format.Sprintf("%05.2f -> 0x%x", 3.14159, 255)
	fmt.Println(out) // 03.14 -> 0xff

	// Arbitrary-precision Bignum, full width.
	z := new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil)
	out, _ = format.Sprintf("%d", z)
	fmt.Println(out) // 1000000000000000000000000000000

	// Ruby's two's-complement notation for negative non-decimal bases.
	out, _ = format.Sprintf("%#x", -255)
	fmt.Println(out) // 0x..f01

	// Named references from a hash; KeyError on a missing key.
	out, _ = format.Sprintf("%<name>s is %<age>d", map[string]any{
		"name": "Ada", "age": 36,
	})
	fmt.Println(out) // Ada is 36

	// MRI-matching errors.
	_, err := format.Sprintf("%d")
	fmt.Println(err) // ArgumentError: too few arguments
}

Conversions

Verb Meaning
d i u signed decimal integer (Bignum-aware)
f fixed-point float
e E scientific float
g G shortest float (trailing zeros trimmed; kept under #)
a A hexadecimal float
s to_s
p inspect
x X o b B hex / octal / binary integer (.. two's-complement form)
c character (code point or one-character string)
%% a literal percent

Flags - + space 0 # · width/precision numeric, * (from args), and named · %n$ absolute argument references · %<name> and %{name} hash references · Bignum at full precision · the Inf / -Inf / NaN spellings.

Argument model

Sprintf(format string, args ...any) (string, error) accepts plain Go values and adapts them internally. A host such as rbgo that already holds typed value objects implements the small Value interface and calls Format(format string, args []Value, named *NamedArgs) (string, error), so its objects are formatted directly with no intermediate copy. A *NamedArgs, map[string]Value, or map[string]any supplies the hash for named references.

Tests & coverage

The package is verified two ways:

  • a differential test runs a broad corpus through both this package and the live MRI ruby oracle, comparing output — and raised exception class and message — byte-for-byte (it self-skips where ruby is absent, e.g. the qemu and Windows lanes);
  • a deterministic golden test embeds the MRI-captured results so the oracle-free lanes still exercise the entire surface and hold the 100.0% coverage gate.
go test ./...

CI enforces 100% coverage, go vet, and CGO=0 builds on all six 64-bit Go targets: amd64, arm64, riscv64, loong64, ppc64le, s390x.

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-format/format authors.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages