A Guide on Converting a Hash to a Struct in Ruby

Before we get deeper in to the conversion process, let us all first identify the difference between the two – the hash and the struct. This will let us help answer the question why some prefer using the struct than hash in Ruby.

Differentiating Hash from Struct

Hash is the collection of the key-value pairs and it’s the same to the Array, except the fact that the indexing was made through the arbitrary keys of any types of objects (not the integer index). An order in which are traversing a hash by value or key may seem arbitrary – and generally may not be in the intersection order. On the other hand, struct is the more convenient type of way to bundle the numbers of attributes together. This is by the access methods without needing to write explicit classes.

Struct will allow an instance to be generated with set of accessors and this looks powerful and convenient for the user. Even though hash can do similar thing, it is coup with some pitfalls, which you may don’t like. Struct is easier to understand, which will lead the users to a more maintainable coding. Furthermore, it is worth noting that struct outperforms hash when it comes data retrieval speed, which will let you know that struct can be a better choice compared to the hash for the configuration needing to be accessed in a repeated manner at the runtime.

Converting Hash to Struct in Ruby

With the fact we know about the two, many will perhaps prefer using struct rather than hash. But what we want to focus here is that behind the low performance given by hash, they still can become advantageous. If you can’t use it on its own little way, then convert it into struct so better usability can be achieved.

If you have already defined the struct and you wanted to initiate converting hash to struct, we can help you by using the following methods in a given example below. If you wanted to convert has to a struct in Ruby, let us say for example we have a given of:

h = { :a => 1, :b => 2 }
and want to have a struct such as:
s.a == 1
s.b == 2

To convert, you can do any of these methods:
Conversion Method 1:

On this method, the result will appear to be OpenStruct and not specifically as struct:

pry(main)> require 'ostruct'
pry(main)> s = OpenStruct.new(h)
=> #
pry(main)> puts s.a, s.b
1
2

Conversion Method 2:

If you have struct defined already and want to start something with a hash, you can follow this:

Person = Struct.new(:first_name, :last_name, :age)

person_hash = { first_name: "Foo", last_name: "Bar", age: 29 }

person = Person.new(*person_hash.values_at(*Person.members))

=> #

Conversion Method 3:

Since the hash key order was guaranteed in the Ruby 1.9+, you can follow this:

s = Struct.new(*(k = h.keys)).new(*h.values_at(*k))

The hash to struct conversion example we provided can help, but if you want a more extensive idea, come to professionals for formal assistance.