Reputation: 797
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
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
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