Should I use a Struct or an OpenStruct (Ruby)?
At first glace the choice between using a Struct
or an OpenStruct
is just preference. They are very similar and (mostly) behave the same way.
require 'ostruct'
P = Struct.new(:age, :name)
sam = P.new(40, "Sam")
# => #<struct P age=40, name="Sam">
samantha = OpenStruct.new(age: 40, name: "Samantha")
# => #<OpenStruct age=40, name="Samantha">
Pretty similar, right?
Actually there are some differences and these should inform your choice. The choice revolves around the specific characteristics of your data structure so lets look at those.
Ruby Struct:
A Ruby Struct is lightweight and performance and it is used for small and efficient class. It provides a convenient way to define classes with a set of attributes without explicitly writing a full class definition. The attributes are defined at the time of creating the Struct
and are immutable once instantiated.
Human = Struct.new(:name, :age, :likes_waffles)
jim = Human.new("Jim", 13, true)
jim.name # "Jim"
jim.age # 30
jim.likes_waffles # true
A Struct
is fit for when you have a fixed set of attributes and you want a quick, easy and performant representation of your data. It is meant to create simple data structures with an emphasis on speed and memory efficiency.
Ruby OpenStruct:
Naturally, this means that OpenStructs are heavier on the memory and are also slower.
So what does OpenStruct
provide?
An OpenStruct
is a more flexible and dynamic in it’s approach to creating objects. It allows you to add attributes on the fly, which is useful for creating data structures that may need to change or evolve as you add new attributes.
require 'ostruct'
jill = OpenStruct.new(name: "Jill", age: 23)
jill.name # "Jill"
jill.age # 23
# Give here a hometown
jill.hometown = "London"
# Why not a favorite color?
jill.favorite_color = "green"
# Whatever attribute you like
jill.number_of_chickens_owned = 33
So an OpenStruct
is less performant than Struct
because it stores attributes in a hash but you can add whatever you like to it at anytime. Sounds like an OpenStruct
would be good for metaprogramming.
How to choose between a Struct and an OpenStruct
- A
Struct
is generally more efficient and tends to use less memory if performance is critical. - A
Struct
is also better if you have a fixed set of attributes. - An
OpenStruct
is more flexible if you need the ability to add attributes dynamically. - An
OpenStruct
can be more readable and concise.
So to wrap up. If you value performance and have a clear, fixed structure for your data, go for Struct
. If flexibility and dynamic attribute handling are more critical, opt for OpenStruct
.