You could use the double splat operator **
in conjunction with logical or (double pipes) ||
inside the initialize
method to achieve the same effect.
class Person
def initialize(**options)
@name = options[:name] || options[:first_name] << ' ' << options[:last_name]
end
end
james = Person.new(name: 'James')
#=> #<Person @name="James">
jill_masterson = Person.new(first_name: 'Jill', last_name: 'Masterson')
#=> #<Person @name="Jill Masterson">
However, if a new Person
is created without a first_name
, then the append <<
operation will fail with NoMethodError: undefined method '<<' for nil:NilClass
. Here is a refactored initialize
method to handle this case (using strip
to remove whitespace if either option is excluded).
class Person
def initialize(**options)
@name = options[:name] || [ options[:first_name] , options[:last_name] ].join(' ').strip
end
end
goldfinger = Person.new(last_name: 'Goldfinger')
#=> #<Person @name="Goldfinger">
oddjob = Person.new(first_name: 'Oddjob')
#=> #<Person @name="Oddjob">
In fact, this approach handles calling Person.new
without arguments or with an unexpected key to return the new instance with @name
set to an empty string:
nameless = Person.new
#=> <#Person @name="">
middle_malcom = Person.new(middle_name: 'Malcom')
#=> <#Person @name="">