# OpenStruct < Object
(from ruby core)
An OpenStruct is a data structure, similar to a Hash, that allows the
definition of arbitrary attributes with their accompanying values. This
is accomplished by using Ruby's metaprogramming to define methods on the
person = OpenStruct.new
person.name = "John Smith"
person.age = 70
person.name # => "John Smith"
person.age # => 70
person.address # => nil
An OpenStruct employs a Hash internally to store the attributes and
values and can even be initialized with one:
australia = OpenStruct.new(:country => "Australia", :capital => "Canberra")
# => #<OpenStruct country="Australia", capital="Canberra">
Hash keys with spaces or characters that could normally not be used for
method calls (e.g. `()*`) will not be immediately available on the
OpenStruct object as a method for retrieval or assignment, but can still
be reached through the Object#send method or using .
measurements = OpenStruct.new("length (in inches)" => 24)
measurements[:"length (in inches)"] # => 24
measurements.send("length (in inches)") # => 24
message = OpenStruct.new(:queued? => true)
message.queued? # => true
message.queued? # => false
Removing the presence of an attribute requires the execution of the
delete_field method as setting the property value to `nil` will not
remove the attribute.
first_pet = OpenStruct.new(:name => "Rowdy", :owner => "John Smith")
second_pet = OpenStruct.new(:name => "Rowdy")
first_pet.owner = nil
first_pet # => #<OpenStruct name="Rowdy", owner=nil>
first_pet == second_pet # => false
first_pet # => #<OpenStruct name="Rowdy">
first_pet == second_pet # => true
Ractor compatibility: A frozen OpenStruct with shareable values is
An OpenStruct utilizes Ruby's method lookup structure to find and define
the necessary methods for properties. This is accomplished through the
methods method_missing and define_singleton_method.
This should be a consideration if there is a concern about the
performance of the objects that are created, as there is much more
overhead in the setting of these properties compared to using a Hash or
a Struct. Creating an open struct from a small Hash and accessing a few
of the entries can be 200 times slower than accessing the hash directly.
This is a potential security issue; building OpenStruct from untrusted
user data (e.g. JSON web request) may be susceptible to a "symbol denial
of service" attack since the keys create methods and names of methods
are never garbage collected.
This may also be the source of incompatibilities between Ruby versions:
o = OpenStruct.new
o.then # => nil in Ruby < 2.6, enumerator for Ruby >= 2.6
Builtin methods may be overwritten this way, which may be a source of
bugs or security issues:
o = OpenStruct.new
o.methods # => [:to_h, :marshal_load, :marshal_dump, :each_pair, ...
o.methods = [:foo, :bar]
o.methods # => [:foo, :bar]
To help remedy clashes, OpenStruct uses only protected/private methods
ending with `!` and defines aliases for builtin public methods by adding
o = OpenStruct.new(make: 'Bentley', class: :luxury)
o.class # => :luxury
o.class! # => OpenStruct
It is recommended (but not enforced) to not use fields ending in `!`;
Note that a subclass' methods may not be overwritten, nor can
OpenStruct's own methods ending with `!`.
For all these reasons, consider not using OpenStruct at all.
: [not documented]
# Class methods:
# Instance methods: