Documentation
¶
Overview ¶
Package ostruct is a pure-Go (CGO=0), MRI-4.0.5-faithful core for Ruby's OpenStruct (require "ostruct").
It provides the data structure underneath OpenStruct: an ordered attribute table keyed by Symbol, together with the accessors, conversions, comparison, and inspection that MRI exposes. The dynamic method_missing get/set glue and respond_to_missing? — the part that turns an arbitrary method name into a table read or write at call time — stays in the host runtime (rbgo) and is implemented in terms of this table (Get/Set/RespondToField).
The table preserves insertion order: to_h, each_pair, and inspect all walk keys in the order they were first defined, matching MRI.
Values are held as opaque any. So that Inspect and dig can match MRI without depending on a particular value model, the package renders values through the Inspector and Digger interfaces (the host's Ruby values implement these), and falls back to a built-in renderer covering the common Ruby scalar/collection shapes for deterministic, ruby-free testing.
Index ¶
- func ClassName(v any) string
- func InspectValue(v any) string
- type ArgumentError
- type Digger
- type Inspector
- type NameError
- type OpenStruct
- func (o *OpenStruct) DeleteField(name any) (any, error)
- func (o *OpenStruct) Dig(keys ...any) (any, error)
- func (o *OpenStruct) EachPair(fn func(key Symbol, value any) bool)
- func (o *OpenStruct) Eql(other any) bool
- func (o *OpenStruct) Equal(other any) bool
- func (o *OpenStruct) Get(name any) any
- func (o *OpenStruct) Index(name any) any
- func (o *OpenStruct) Inspect() string
- func (o *OpenStruct) Len() int
- func (o *OpenStruct) Members() []Symbol
- func (o *OpenStruct) RespondToField(name any) bool
- func (o *OpenStruct) Set(name, value any) any
- func (o *OpenStruct) SetIndex(name, value any) any
- func (o *OpenStruct) String() string
- func (o *OpenStruct) ToH() []Pair
- type Pair
- type Symbol
- type TypeError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClassName ¶
ClassName returns the Ruby class name MRI would use in a #dig TypeError. Hosts expose it via a Classer; built-in Go shapes map to their Ruby class.
func InspectValue ¶
InspectValue renders v as Ruby's Object#inspect would. A value implementing Inspector supplies its own text; otherwise the built-in renderer covers the common Ruby scalar and collection shapes (nil, true/false, Integer, Float, String, Symbol, and []any/[]Pair as Array/Hash) for deterministic, ruby-free rendering.
Types ¶
type ArgumentError ¶
type ArgumentError struct{ Message string }
ArgumentError is raised by OpenStruct.Dig when called with no keys, matching MRI's `wrong number of arguments (given 0, expected 1+)`.
func (*ArgumentError) Error ¶
func (e *ArgumentError) Error() string
type Digger ¶
Digger is the dig protocol: a value that can itself be dug into (Array, Hash, Struct, or a nested OpenStruct in MRI). OpenStruct.Dig delegates the remaining keys to it, matching Ruby's `obj.dig(*keys)`.
type Inspector ¶
type Inspector interface {
Inspect() string
}
Inspector renders a value the way Ruby's Object#inspect would. The host runtime's Ruby values implement it so OpenStruct.Inspect reproduces MRI byte-for-byte; values that do not implement it are rendered by InspectValue.
type NameError ¶
type NameError struct{ Message string }
NameError is raised by OpenStruct.DeleteField for an absent field. Its message matches MRI: `no field 'NAME' in #<OpenStruct ...>`.
type OpenStruct ¶
type OpenStruct struct {
// contains filtered or unexported fields
}
OpenStruct is the ordered attribute table backing Ruby's OpenStruct. Keys are Symbols; insertion order is preserved across to_h, each_pair, and inspect.
The table stores its entries as an insertion-ordered slice of [Pair]s (each Key a Symbol) alongside a Symbol→position index. Keeping the values *in* the ordered slice — rather than in a separate map keyed by the ordered keys — lets OpenStruct.ToH serialise with a single slice copy and no per-key hashing, while random access (OpenStruct.Get/OpenStruct.Set) stays a single map probe.
The zero value is not ready for use; construct with New.
func New ¶
func New(hash ...Pair) *OpenStruct
New builds an OpenStruct seeded from hash, whose keys are interned to Symbols in iteration order. A nil hash yields an empty struct. This is MRI's `OpenStruct.new(hash)`.
The seed is given as ordered key/value Pairs so that insertion order — which MRI preserves from the source hash — is deterministic. Pass no pairs for an empty struct.
func (*OpenStruct) DeleteField ¶
func (o *OpenStruct) DeleteField(name any) (any, error)
DeleteField removes field name, returning its prior value. It raises a *NameError if the field is not defined — MRI's `delete_field`.
func (*OpenStruct) Dig ¶
func (o *OpenStruct) Dig(keys ...any) (any, error)
Dig walks keys: the first key reads this struct's field, and any remaining keys are delegated to that value's dig protocol (Digger, or a nested *OpenStruct). With no keys it returns an *ArgumentError; a key whose value is missing yields nil; an intermediate value that cannot be dug into yields a *TypeError. This is MRI's `dig(*keys)`.
func (*OpenStruct) EachPair ¶
func (o *OpenStruct) EachPair(fn func(key Symbol, value any) bool)
EachPair calls fn for every field in insertion order, stopping early if fn returns false. It mirrors MRI's `each_pair` (the host wraps it to yield to a Ruby block or return an Enumerator).
func (*OpenStruct) Eql ¶
func (o *OpenStruct) Eql(other any) bool
Eql is an alias of OpenStruct.Equal for MRI's `eql?`, which OpenStruct defines identically to `==`.
func (*OpenStruct) Equal ¶
func (o *OpenStruct) Equal(other any) bool
Equal reports OpenStruct equality the way MRI's `==`/`eql?` do: other must be an *OpenStruct (subclasses included, since MRI uses is_a?) and the two tables must be equal as ordered Symbol→value maps. Values compare by Go ==, with a nil-safe fallback for non-comparable values via fmt.
func (*OpenStruct) Get ¶
func (o *OpenStruct) Get(name any) any
Get returns the value of field name (Symbol or string), or nil if the field is not defined — MRI's reader for an undefined attribute returns nil.
func (*OpenStruct) Index ¶
func (o *OpenStruct) Index(name any) any
Index is the `[]` accessor: it reads field name (Symbol or string).
func (*OpenStruct) Inspect ¶
func (o *OpenStruct) Inspect() string
Inspect renders the struct as MRI does: `#<OpenStruct k=v, ...>` with fields in insertion order and each value rendered by its Inspector (or InspectValue); an empty struct renders as `#<OpenStruct>`.
func (*OpenStruct) Members ¶
func (o *OpenStruct) Members() []Symbol
Members returns the field names (Symbols) in insertion order — MRI's `members`/`to_h.keys`.
func (*OpenStruct) RespondToField ¶
func (o *OpenStruct) RespondToField(name any) bool
RespondToField reports whether field name is defined. The host's respond_to_missing? combines this with its own `name end_with? "="` rule for writers; this core answers only "is this attribute present?".
func (*OpenStruct) Set ¶
func (o *OpenStruct) Set(name, value any) any
Set defines (or overwrites) field name with value, returning value. A new field is appended to the insertion order; overwriting an existing field keeps its position. This is MRI's writer (`o.name = value` / `o[name] = value`).
func (*OpenStruct) SetIndex ¶
func (o *OpenStruct) SetIndex(name, value any) any
SetIndex is the `[]=` accessor: it writes field name (Symbol or string) and returns value.
func (*OpenStruct) String ¶
func (o *OpenStruct) String() string
String is the `to_s` alias of OpenStruct.Inspect.
func (*OpenStruct) ToH ¶
func (o *OpenStruct) ToH() []Pair
ToH returns the table as ordered key/value [Pair]s with Symbol keys in insertion order — MRI's `to_h` (whose Hash preserves that order).
Because the entries are already stored in insertion order, this is a single slice copy: no per-key hash probe is needed to rebuild the order. A fresh slice is returned (never the internal backing array), so callers may mutate the result exactly as Ruby's `to_h` hands back an independent Hash.
type Pair ¶
Pair is one ordered key/value entry used to seed New and returned by OpenStruct.ToH/OpenStruct.EachPair. Key may be a Symbol or string.
type Symbol ¶
type Symbol string
Symbol is the key type of an OpenStruct table. MRI keys every OpenStruct attribute by Symbol; strings handed to OpenStruct.Get, OpenStruct.Set, and the bracket accessors are interned to Symbol via ToSym.
