15

Ruby version: 2.3.1

It does not appear that Ruby Structs can be declared using keyword params. Is there a way to do this within Struct?

Example:

MyStruct = Struct.new(:fname, :lname)
=> MyStruct

my_struct = MyStruct.new(fname: 'first', lname: 'last')
=> <struct MyStruct fname={:fname=>"first", :lname=>"last"}, lname=nil>

my_struct.fname
=> {:fname=>"first", :lname=>"last"}

my_struct.lname
=> nil

2 Answers 2

26

With Ruby 2.5, you can set the keyword_init option to true.

MyStruct = Struct.new(:fname, :lname, keyword_init: true)
# => MyStruct(keyword_init: true)
irb(main):002:0> my_struct = MyStruct.new(fname: 'first', lname: 'last')
# => #<struct MyStruct fname="first", lname="last">
Sign up to request clarification or add additional context in comments.

1 Comment

As of Ruby 3.2+, you no longer need to specify keyword_init: true. Structs can automatically be initialized by keyword arguments. ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released
2
my_struct = MyStruct.new(fname: 'first', lname: 'last')

is the same as

my_struct = MyStruct.new({ fname: 'first', lname: 'last' })
  #=> #<struct MyStruct fname={:fname=>"first", :lname=>"last"}, lname=nil>

(one argument) so fname is set equal to the argument and lname is set to nil, in the same way that x, y = [2]; x #=> 2; y #=> nil.

This is because Ruby allows one to omit the braces when a hash is the argument of a method.

You may wish to search SO for related questions such as this one.

3 Comments

Ok, that makes sense. However, I'm still not sure how to get the keyword arguments to work. I can pass in two hashes ie MyStruct.new({fname: 'first'}, {lname: 'last'}) but that will give me a hash to work with rather than a string.
I seemed to have missed your 3-month-old comment. my_struct = MyStruct.new({fname: 'first'}, {lname: 'last'}); my_struct.fname #=> {:fname=>"first"}; my_struct.lname #=> {:lname=>"last"}. Does that answer your question?
I wrote a gem (github.com/rohitpaulk/named_struct) that defines a NamedStruct class that inherits from Struct, and changes the initialization behavior to accept keyword arguments instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.