How--and when--To Use a Struct

| Comments

Recently I’ve been going through my ever growing (and then shrinking, and then growing again) list of new things/situations I’ve been introduced to via my code base at work. Which lead me to dig a little deeper into Ruby structs.

A struct is a simple way to bundle attributes together without having to explicitly define a class, all the while giving you accessor methods for those attributes. You can read the Ruby Docs about structs here.

We’ll use the example of creating people.

A struct can be created very easily in two different ways:

  Struct.new("Person", :name, :age, :address)
  Person = Struct.new(:name, :age, :address)

So now we have our Person struct, Struct::Person. This gives us really easy accessor methods for all three attributes of the struct that we defined.

We can easily create new instances of this struct:

  Struct::Person.new("Victoria", 24, "1835 University Circle")
  victoria = Person.new("Victoria", 24, "1835 University Circle")

So how do we access the attribtues of this new instance of the struct?

  victoria["name"] #=> "Victoria"
  victoria["age"] #=> 24
  victoria["address"] #=> "1835 University Circle"

You can also change the values of an instance of the struct:

  victoria["name"] = "Vic"
  victoria["name"] #=> "Vic"

So what’s the difference between Struct and OpenStruct? OpenStruct doesn’t require explicitly defined attributes. You can create them on the fly.

person = OpenStruct.new
person.name = "Victoria"
person.age = 24
person.date_of_birth = "June 1, 1988"

Notice when we created the OpenStruct, we didn’t define any attribute fields, just the name.

Both Struct and OpenStruct closely resemble a hash, so why not just use that? You should think of a Struct as a convience class when you just want to store attributes and read/write to them with regular methods. A hash is a possibility, but a hash isn’t fixed. There can be an infinite and varying number of key-value pairs. A Struct is the way to go when modeling out more complex objects with a known set of attributes.

Comments