Avoiding nil errors
Here is a quick way to avoid nil errors and get better failures in Ruby and Ruby on Rails. Convert hashes with known keys into Structs: data = { a: 1, b: 2, c: 3} ... MyData = Struct.new(:a,:b,:c) data = MyData.new(a: 1, b: 2, c: 3) Structs will throw if you introduce a typo instead of returning nil. This tightens your feedback loops and reduces debugging time. hash[:d] => nil struct[:d] => in 'Struct#[]': no member 'd' in struct (NameError) That is cool. What about in more fluid situations like user input? You can convert arbitrary incoming hashes into known structs quickly with the following: params = {a: 1, b: 2, c: 3, x: 9, z: 0} MyData.new(**params.slice(*MyData.members)) Pitfalls While Structs have much the same interface as hashes, there are some tricky differences. Hash#each is equivalent to Struct#each_pair. Hash#keys is equivalent to Struct#members. There is no equivalent to Hash#fetch.

Here is a quick way to avoid nil errors and get better failures in Ruby and Ruby on Rails. Convert hashes with known keys into Structs:
data = { a: 1, b: 2, c: 3}
...
MyData = Struct.new(:a,:b,:c)
data = MyData.new(a: 1, b: 2, c: 3)
Structs will throw if you introduce a typo instead of returning nil. This tightens your feedback loops and reduces debugging time.
hash[:d] => nil
struct[:d] => in 'Struct#[]': no member 'd' in struct (NameError)
That is cool. What about in more fluid situations like user input? You can convert arbitrary incoming hashes into known structs quickly with the following:
params = {a: 1, b: 2, c: 3, x: 9, z: 0}
MyData.new(**params.slice(*MyData.members))
Pitfalls
While Structs have much the same interface as hashes, there are some tricky differences.
- Hash#each is equivalent to Struct#each_pair.
- Hash#keys is equivalent to Struct#members.
- There is no equivalent to Hash#fetch.