This blog is part of our Ruby 2.5 series.

In Ruby, structs can be created using positional arguments.

Customer = Struct.new(:name, :email)
Customer.new("John", "john@example.com")

This approach works when the arguments list is short. When arguments list increases then it gets harder to track which position maps to which value.

Here if we pass keyword argument then we won’t get any error. But the values are not what we wanted.

Customer.new(name: "John", email: "john@example.com")
=> #<struct Customer name={:name=>"John", :email=>"john@example.com"}, email=nil>

Ruby 2.5 introduced creating structs using keyword arguments. Relevant pull request is here.

However this introduces a problem. How do we indicate to Struct if we want to pass arguments using position or keywords.

Takashi Kokubun suggested to use keyword_argument as an identifier.

Customer = Struct.new(:name, :email, keyword_argument: true)
Customer.create(name: "John", email: "john@example.com")

Matz suggested to change the name to keyword_init.

So in Ruby 2.5 we can create structs using keywords as long as we are passing keyword_init.

Customer = Struct.new(:name, :email, keyword_init: true)

Customer.new(name: "John", email: "john@example.com")
=> #<struct Customer name="John", email="john@example.com">