Struct
is a collection of attributes with accessor methods,
without having to write the class explicitly.
A Struct
class generates a new subclass that contains a set of members and their values.
For each member, a reader and writer method is created similar to #attr_accessor
.
> Vehicle = Struct.new(:make, :model)
> Vehicle.superclass
=> Struct
> Vehicle.ancestors
=> [Vehicle, Struct, Enumerable, Object, Kernel, BasicObject]
Since Struct
is bundled with Enumerable
module,
we can take advantage of methods like #filter
, #count
, #include?
, #uniq
, #tally
etc.
Example
> Vehicle = Struct.new(:make, :model)
> Vehicle["Dodge", "Hellcat"]
=> #<struct Vehicle make="Dodge", model="Hellcat">
> bike = Vehicle.new("Triumph", "Daytona")
> bike
=> #<struct Vehicle make="Triumph", model="Daytona">
> bike.make = "Yamaha"
> bike["model"] = "R1"
> bike
=> #<struct Vehicle make="Yamaha", model="R1">
Structure with name under Struct
We can pass in a class_name
argument,
which then will be scoped under Struct
to define the class.
> Struct.new("Vehicle", :make, :model)
=> Struct::Vehicle
> Struct::Vehicle.new("BMW", "S1000RR")
=> #<struct Struct::Vehicle make="BMW", model="S1000RR">
Structure with name of it’s Constant
When the class_name
argument is not passed,
if it’s assigned to a constant then a class with the name of the constant is created otherwise an anonymous class is created.
> Vehicle = Struct.new(:make, :model)
> Vehicle.new("BMW", "S1000RR")
=> #<struct Vehicle make="BMW", model="S1000RR">
> Struct.new(:make, :model)
=> #<Class:0x00007fb4e8ab45b0>
keyword_init
argument
If this is given while defining the Struct, the #new
method will accept keyword arguments instead of normal arguments.
> Vehicle = Struct.new(:make, :model, keyword_init: true)
> Vehicle.new(make: "BMW", model: "S1000RR")
=> #<struct Vehicle make="BMW", model="S1000RR">
Customize
> Vehicle = Struct.new(:make, :model, :number_of_wheels) do
> def bike?
> number_of_wheels == 2
> end
> end
> hellcat = Vehicle.new("Dodge", "Hellcat", 4)
> hellcat.bike?
=> false
Equality
Returns true
if other
has the same class and values for it’s members.
Object#==
is used for comparison.
> Customer = Struct.new(:name, :address, :zip)
> joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
> smith = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
> joe == smith #=> true
#values
method
Returns values of it’s members as an array.
> Customer = Struct.new(:name, :address, :zip)
> joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
> joe.values
=> ["Joe Smith", "123 Maple, Anytown NC", 12345]
#members
method
Returns it’s members as an array.
> Customer = Struct.new(:name, :address, :zip)
> joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
> joe.members
=> [:name, :address, :zip]
#dig
method
Extracts the nested value.
Check out my previous post on #dig
for more details.
> Address = Struct.new(:lane, :city, :location_data)
> Customer = Struct.new(:name, :address)
> address = Address.new("123 Maple", "Anytown NC", { lane: { street: "123 Watson Street" }, zip: 12345 })
> joe = Customer.new("Joe Smith", address)
> joe.dig(:address, :location_data, :lane, :street)
=> "123 Watson Street"
Finally,
In this post,
we have checked all the details about ruby’s Struct
class and some of it’s useful methods.