Leo Net
Leo Net

Reputation: 797

Ruby 2.1+ Keyword Arguments Initializers Syntax

Sandi Metz in Practical Object-Oriented Design in Ruby has this example on page 47:

class Gear
    attr_reader :chainring, :cog, :wheel
    def initialize(args)
        @chainring = args[:chainring]
        @cog       = args[:cog]
        @wheel     = args[:wheel]
    end
    ...
end

In Ruby 2.1+ can the same be expressed as:

class Gear
    attr_reader :chainring, :cog, :wheel
    def initialize(chainring:, cog:, wheel:)
        @chainring = chainring
        @cog       = cog
        @wheel     = wheel
    end
    ...
end

Would these two be equivalent? They do seem to work in the same manner.

Upvotes: 1

Views: 145

Answers (2)

Kranthi
Kranthi

Reputation: 1417

In the first method, You need to pass a hash so it takes the values from the keys and if the keys are not present, it assigns nil

[42] pry(main)> Gear.new({:cog => 1})
=> #<Gear:0xb9d36bc @chainring=nil, @cog=1, @wheel=nil>

In the second method you need to pass exact number of arguments. If you pass any extra arguments you get the ArgumentError

[38] pry(main)> class Gear
[38] pry(main)*   attr_reader :chainring, :cog, :wheel    
[38] pry(main)*   def initialize(args)    
[38] pry(main)*     @chainring = args[:chainring]        
[38] pry(main)*     @cog       = args[:cog]        
[38] pry(main)*     @wheel     = args[:wheel]        
[38] pry(main)*   end      
[38] pry(main)*   ...    
Error: there was a problem executing system command: ..
[38] pry(main)* end  
=> :initialize
[39] pry(main)> Gear.new(1,2,3,4,5,)
ArgumentError: wrong number of arguments (5 for 1)
from (pry):38:in `initialize'

Upvotes: 0

khagler
khagler

Reputation: 4056

In the first method, any extra keys in the args hash will be ignored, and if any of the three specified are missing the appropriate variable will be assigned nil. In the second method, any additional or missing arguments will produce an ArgumentError exception.

Upvotes: 3

Related Questions