class Struct
Class Struct provides a convenient way to create a simple class that can store and fetch values.
This example creates a subclass of Struct, Struct::Customer; the first argument, a string, is the name of the subclass; the other arguments, symbols, determine the members of the new subclass.
Customer = Struct.new('Customer', :name, :address, :zip) Customer.name # => "Struct::Customer" Customer.class # => Class Customer.superclass # => Struct
Corresponding to each member are two methods, a writer and a reader, that store and fetch values:
methods = Customer.instance_methods false methods # => [:zip, :address=, :zip=, :address, :name, :name=]
An instance of the subclass may be created, and its members assigned values, via method ::new:
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe # => #<struct Struct::Customer name="Joe Smith", address="123 Maple, Anytown NC", zip=12345>
The member values may be managed thus:
joe.name # => "Joe Smith" joe.name = 'Joseph Smith' joe.name # => "Joseph Smith"
And thus; note that member name may be expressed as either a string or a symbol:
joe[:name] # => "Joseph Smith" joe[:name] = 'Joseph Smith, Jr.' joe['name'] # => "Joseph Smith, Jr."
See Struct::new.
What’s Here
First, what’s elsewhere. Class Struct:
-
Inherits from class Object.
-
Includes module Enumerable, which provides dozens of additional methods.
See also Data, which is a somewhat similar, but stricter concept for defining immutable value objects.
Here, class Struct provides methods that are useful for:
Methods for Creating a Struct Subclass
Methods for Querying
Methods for Comparing
-
==: Returns whether a given object is equal toself, using==to compare member values. -
eql?: Returns whether a given object is equal toself, usingeql?to compare member values.
Methods for Fetching
-
[]: Returns the value associated with a given member name. -
to_a(aliased asvalues,deconstruct): Returns the member values inselfas an array. -
deconstruct_keys: Returns a hash of the name/value pairs for given member names. -
dig: Returns the object in nested objects that is specified by a given member name and additional arguments. -
members: Returns an array of the member names. -
select(aliased asfilter): Returns an array of member values fromself, as selected by the given block. -
values_at: Returns an array containing values for given member names.
Methods for Assigning
-
[]=: Assigns a given value to a given member name.
Methods for Iterating
-
each: Calls a given block with each member name. -
each_pair: Calls a given block with each member name/value pair.
Methods for Converting
Public Class Methods
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/struct.rb, line 9 def self.json_create(object) new(*object['v']) end
() → bool?
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 267
def self.keyword_init?: () -> bool?
Returns true if the class was initialized with keyword_init: true. Otherwise returns nil or false.
Examples: Foo = Struct.new(:a) Foo.keyword_init? # => nil Bar = Struct.new(:a, keyword_init: true) Bar.keyword_init? # => true Baz = Struct.new(:a, keyword_init: false) Baz.keyword_init? # => false
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 250
def self.members: () -> Array[Symbol]
Returns the member names of the Struct descendant as an array:
Customer = Struct.new(:name, :address, :zip) Customer.members # => [:name, :address, :zip]
(string? classname, *interned fields, ?keyword_init: boolish?) ?{ (singleton(Struct)) [self: singleton(Struct)] → void } → untyped
(Symbol field1, *interned fields, ?keyword_init: boolish?) ?{ (singleton(Struct)) [self: singleton(Struct)] → void } → untyped
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 238
def self.new: (string? classname, *interned fields, ?keyword_init: boolish?) ?{ (singleton(Struct)) [self: singleton(Struct)] -> void } -> untyped
| (Symbol field1, *interned fields, ?keyword_init: boolish?) ?{ (singleton(Struct)) [self: singleton(Struct)] -> void } -> untyped
Struct.new returns a new subclass of Struct. The new subclass:
-
May be anonymous, or may have the name given by
class_name. -
May have members as given by
member_names. -
May have initialization via ordinary arguments, or via keyword arguments
The new subclass has its own method ::new; thus:
Foo = Struct.new('Foo', :foo, :bar) # => Struct::Foo f = Foo.new(0, 1) # => #<struct Struct::Foo foo=0, bar=1>
Class Name
With string argument class_name, returns a new subclass of Struct named Struct::<em>class_name</em>:
Foo = Struct.new('Foo', :foo, :bar) # => Struct::Foo Foo.name # => "Struct::Foo" Foo.superclass # => Struct
Without string argument class_name, returns a new anonymous subclass of Struct:
Struct.new(:foo, :bar).name # => nil
Block
With a block given, the created subclass is yielded to the block:
Customer = Struct.new('Customer', :name, :address) do |new_class| p "The new subclass is #{new_class}" def greeting "Hello #{name} at #{address}" end end # => Struct::Customer dave = Customer.new('Dave', '123 Main') dave # => #<struct Struct::Customer name="Dave", address="123 Main"> dave.greeting # => "Hello Dave at 123 Main"
Output, from Struct.new:
"The new subclass is Struct::Customer"
Member Names
Symbol arguments member_names determines the members of the new subclass:
Struct.new(:foo, :bar).members # => [:foo, :bar] Struct.new('Foo', :foo, :bar).members # => [:foo, :bar]
The new subclass has instance methods corresponding to member_names:
Foo = Struct.new('Foo', :foo, :bar) Foo.instance_methods(false) # => [:foo, :bar, :foo=, :bar=] f = Foo.new # => #<struct Struct::Foo foo=nil, bar=nil> f.foo # => nil f.foo = 0 # => 0 f.bar # => nil f.bar = 1 # => 1 f # => #<struct Struct::Foo foo=0, bar=1>
Singleton Methods
A subclass returned by Struct.new has these singleton methods:
-
Method::newcreates an instance of the subclass:Foo.new # => #<struct Struct::Foo foo=nil, bar=nil> Foo.new(0) # => #<struct Struct::Foo foo=0, bar=nil> Foo.new(0, 1) # => #<struct Struct::Foo foo=0, bar=1> Foo.new(0, 1, 2) # Raises ArgumentError: struct size differs # Initialization with keyword arguments: Foo.new(foo: 0) # => #<struct Struct::Foo foo=0, bar=nil> Foo.new(foo: 0, bar: 1) # => #<struct Struct::Foo foo=0, bar=1> Foo.new(foo: 0, bar: 1, baz: 2) # Raises ArgumentError: unknown keywords: baz
-
Method:inspectreturns a string representation of the subclass:Foo.inspect # => "Struct::Foo"
-
Method::membersreturns an array of the member names:Foo.members # => [:foo, :bar]
Keyword Argument
By default, the arguments for initializing an instance of the new subclass can be both positional and keyword arguments.
Optional keyword argument keyword_init: allows to force only one type of arguments to be accepted:
KeywordsOnly = Struct.new(:foo, :bar, keyword_init: true) KeywordsOnly.new(bar: 1, foo: 0) # => #<struct KeywordsOnly foo=0, bar=1> KeywordsOnly.new(0, 1) # Raises ArgumentError: wrong number of arguments PositionalOnly = Struct.new(:foo, :bar, keyword_init: false) PositionalOnly.new(0, 1) # => #<struct PositionalOnly foo=0, bar=1> PositionalOnly.new(bar: 1, foo: 0) # => #<struct PositionalOnly foo={:foo=>1, :bar=>2}, bar=nil> # Note that no error is raised, but arguments treated as one hash value # Same as not providing keyword_init: Any = Struct.new(:foo, :bar, keyword_init: nil) Any.new(foo: 1, bar: 2) # => #<struct Any foo=1, bar=2> Any.new(1, 2) # => #<struct Any foo=1, bar=2>
Public Instance Methods
(untyped other) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 289
def ==: (untyped other) -> bool
Returns true if and only if the following are true; otherwise returns false:
-
other.class == self.class. -
For each member name
name,other.name == self.name.
Examples:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe_jr == joe # => true joe_jr[:name] = 'Joe Smith, Jr.' # => "Joe Smith, Jr." joe_jr == joe # => false
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 495
def []: (index name_or_position) -> Elem
Returns a value from self.
With symbol or string argument name given, returns the value for the named member:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe[:zip] # => 12345
Raises NameError if name is not the name of a member.
With integer argument n given, returns self.values[n] if n is in range; see Array Indexes at Array:
joe[2] # => 12345 joe[-2] # => "123 Maple, Anytown NC"
Raises IndexError if n is out of range.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 524
def []=: (index name_or_position, Elem value) -> Elem
Assigns a value to a member.
With symbol or string argument name given, assigns the given value to the named member; returns value:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe[:zip] = 54321 # => 54321 joe # => #<struct Customer name="Joe Smith", address="123 Maple, Anytown NC", zip=54321>
Raises NameError if name is not the name of a member.
With integer argument n given, assigns the given value to the n-th member if n is in range; see Array Indexes at Array:
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe[2] = 54321 # => 54321 joe[-3] = 'Joseph Smith' # => "Joseph Smith" joe # => #<struct Customer name="Joseph Smith", address="123 Maple, Anytown NC", zip=54321>
Raises IndexError if n is out of range.
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/struct.rb, line 30 def as_json(*) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" { JSON.create_id => klass, 'v' => values, } end
Methods Struct#as_json and Struct.json_create may be used to serialize and deserialize a Struct object; see Marshal.
Method Struct#as_json serializes self, returning a 2-element hash representing self:
require 'json/add/struct' Customer = Struct.new('Customer', :name, :address, :zip) x = Struct::Customer.new.as_json # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]}
Method JSON.create deserializes such a hash, returning a Struct object:
Struct::Customer.json_create(x) # => #<struct Struct::Customer name=nil, address=nil, zip=nil>
Methods Struct#as_json and Struct.json_create may be used to serialize and deserialize a Struct object; see Marshal.
Method Struct#as_json serializes self, returning a 2-element hash representing self:
require 'json/add/struct' Customer = Struct.new('Customer', :name, :address, :zip) x = Struct::Customer.new.as_json # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]}
Method JSON.create deserializes such a hash, returning a Struct object:
Struct::Customer.json_create(x) # => #<struct Struct::Customer name=nil, address=nil, zip=nil>
Returns the values in self as an array:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]
Related: members.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 667
def deconstruct_keys: (Array[index & Hash::_Key]? indices) -> Hash[index & Hash::_Key, Elem]
Returns a hash of the name/value pairs for the given member names.
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) h = joe.deconstruct_keys([:zip, :address]) h # => {:zip=>12345, :address=>"123 Maple, Anytown NC"}
Returns all names and values if array_of_names is nil:
h = joe.deconstruct_keys(nil) h # => {:name=>"Joseph Smith, Jr.", :address=>"123 Maple, Anytown NC", :zip=>12345}
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 637
def dig: (index name_or_position) -> Elem
| (index name_or_position, untyped, *untyped) -> untyped
Finds and returns an object among nested objects. The nested objects may be instances of various classes. See Dig Methods.
Given symbol or string argument name, returns the object that is specified by name and identifiers:
Foo = Struct.new(:a) f = Foo.new(Foo.new({b: [1, 2, 3]})) f.dig(:a) # => #<struct Foo a={:b=>[1, 2, 3]}> f.dig(:a, :a) # => {:b=>[1, 2, 3]} f.dig(:a, :a, :b) # => [1, 2, 3] f.dig(:a, :a, :b, 0) # => 1 f.dig(:b, 0) # => nil
Given integer argument n, returns the object that is specified by n and identifiers:
f.dig(0) # => #<struct Foo a={:b=>[1, 2, 3]}> f.dig(0, 0) # => {:b=>[1, 2, 3]} f.dig(0, 0, :b) # => [1, 2, 3] f.dig(0, 0, :b, 0) # => 1 f.dig(:b, 0) # => nil
() → Enumerator[Elem, self]
() { (Elem value) → void } → self
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 444
def each: () -> Enumerator[Elem, self]
| () { (Elem value) -> void } -> self
Calls the given block with the value of each member; returns self:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.each {|value| p value }
Output:
"Joe Smith" "123 Maple, Anytown NC" 12345
Returns an Enumerator if no block is given.
Related: each_pair.
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 468
def each_pair: () -> Enumerator[[Symbol, Elem], self]
| () { ([Symbol, Elem] key_value) -> void } -> self
Calls the given block with each member name/value pair; returns self:
Customer = Struct.new(:name, :address, :zip) # => Customer joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.each_pair {|(name, value)| p "#{name} => #{value}" }
Output:
"name => Joe Smith" "address => 123 Maple, Anytown NC" "zip => 12345"
Returns an Enumerator if no block is given.
Related: each.
(untyped other) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 310
def eql?: (untyped other) -> bool
Returns true if and only if the following are true; otherwise returns false:
-
other.class == self.class. -
For each member name
name,other.name.eql?(self.name).Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe_jr.eql?(joe) # => true joe_jr[:name] = 'Joe Smith, Jr.' joe_jr.eql?(joe) # => false
Related: Object#==.
With a block given, returns an array of values from self for which the block returns a truthy value:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) a = joe.select {|value| value.is_a?(String) } a # => ["Joe Smith", "123 Maple, Anytown NC"] a = joe.select {|value| value.is_a?(Integer) } a # => [12345]
With no block given, returns an Enumerator.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 330
def hash: () -> Integer
Returns the integer hash value for self.
Two structs of the same class and with the same content will have the same hash code (and will compare using Struct#eql?):
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.hash == joe_jr.hash # => true joe_jr[:name] = 'Joe Smith, Jr.' joe.hash == joe_jr.hash # => false
Related: Object#hash.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 342
def inspect: () -> String
Returns a string representation of self:
Customer = Struct.new(:name, :address, :zip) # => Customer joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
Returns the number of members.
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.size #=> 3
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 607
def members: () -> Array[Symbol]
Returns the member names from self as an array:
Customer = Struct.new(:name, :address, :zip) Customer.new.members # => [:name, :address, :zip]
Related: to_a.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 543
def select: () -> Enumerator[Elem, Array[Elem]]
| () { (Elem value) -> boolish } -> Array[Elem]
With a block given, returns an array of values from self for which the block returns a truthy value:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) a = joe.select {|value| value.is_a?(String) } a # => ["Joe Smith", "123 Maple, Anytown NC"] a = joe.select {|value| value.is_a?(Integer) } a # => [12345]
With no block given, returns an Enumerator.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 412
def size: () -> Integer
Returns the number of members.
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.size #=> 3
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 365
def to_a: () -> Array[Elem]
Returns the values in self as an array:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]
Related: members.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 388
def to_h: () -> Hash[Symbol, Elem]
| [K, V] () { (Symbol key, Elem value) -> [K, V] } -> Hash[K, V]
Returns a hash containing the name and value for each member:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) h = joe.to_h h # => {:name=>"Joe Smith", :address=>"123 Maple, Anytown NC", :zip=>12345}
If a block is given, it is called with each name/value pair; the block should return a 2-element array whose elements will become a key/value pair in the returned hash:
h = joe.to_h{|name, value| [name.upcase, value.to_s.upcase]} h # => {:NAME=>"JOE SMITH", :ADDRESS=>"123 MAPLE, ANYTOWN NC", :ZIP=>"12345"}
Raises ArgumentError if the block returns an inappropriate value.
(?JSON::State? state) → String
Source
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/struct.rb, line 49 def to_json(*args) as_json.to_json(*args) end
Returns a JSON string representing self:
require 'json/add/struct' Customer = Struct.new('Customer', :name, :address, :zip) puts Struct::Customer.new.to_json
Output:
{"json_class":"Struct","t":{'name':'Rowdy',"age":null}}
Returns a JSON string representing self:
require 'json/add/struct' Customer = Struct.new('Customer', :name, :address, :zip) puts Struct::Customer.new.to_json
Output:
{"json_class":"Struct","t":{'name':'Rowdy',"age":null}}
Returns a string representation of self:
Customer = Struct.new(:name, :address, :zip) # => Customer joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
Returns the values in self as an array:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]
Related: members.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/struct.rbs, line 594
def values_at: (*int | range[int?] positions) -> Array[Elem]
Returns an array of values from self.
With integer arguments integers given, returns an array containing each value given by one of integers:
Customer = Struct.new(:name, :address, :zip) joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) joe.values_at(0, 2) # => ["Joe Smith", 12345] joe.values_at(2, 0) # => [12345, "Joe Smith"] joe.values_at(2, 1, 0) # => [12345, "123 Maple, Anytown NC", "Joe Smith"] joe.values_at(0, -3) # => ["Joe Smith", "Joe Smith"]
Raises IndexError if any of integers is out of range; see Array Indexes at Array.
With integer range argument integer_range given, returns an array containing each value given by the elements of the range; fills with nil values for range elements larger than the structure:
joe.values_at(0..2) # => ["Joe Smith", "123 Maple, Anytown NC", 12345] joe.values_at(-3..-1) # => ["Joe Smith", "123 Maple, Anytown NC", 12345] joe.values_at(1..4) # => ["123 Maple, Anytown NC", 12345, nil, nil]
Raises RangeError if any element of the range is negative and out of range; see Array Indexes at Array.