Is there a way in Ruby to overload the initialize constructor?

In Java, you can overload constructors:

public Person(String name) { this.name = name; } public Person(String firstName, String lastName) { this(firstName + " " + lastName); } 

Is there a way in Ruby to achieve the same result: two constructors that take different arguments?

+55
ruby
Oct 18 2018-10-18
source share
6 answers

Answer: Yes and No.

You can achieve the same result as in other languages ​​using various mechanisms, including: -

  • Default Values ​​for Arguments
  • Variable argument lists (splat operator)
  • Defining an argument as a hash

The actual language syntax does not allow you to define a method twice, even if the arguments are different.

Given the three options above, they can be implemented with your example as follows

 # As written by @Justice class Person def initialize(name, lastName = nil) name = name + " " + lastName unless lastName.nil? @name = name end end class Person def initialize(args) name = args["name"] + " " + args["lastName"] unless args["lastName"].nil? @name = name end end class Person def initialize(*args) #Process args (An array) end end 

You will often see the second mechanism inside Ruby code, especially in Rails, because it offers the best of both worlds and allows some syntactic sugar to produce beautiful code, in particular, not to attach the hash code in curly braces.

This wikibooks link gives some more evidence.

+63
Oct 18 2018-10-18
source share

I try to do

 class Person def self.new_using_both_names(first_name, last_name) self.new([first_name, last_name].join(" ")) end def self.new_using_single_name(single_name) self.new(single_name) end def initialize(name) @name = name end end 

But I do not know if this is the best approach.

+18
Oct 18 '10 at 22:24
source share
 class Person def initialize(name, lastName = nil) name = name + " " + lastName unless lastName.nil? @name = name end end 
+4
Oct 18 2018-10-18
source share
 class StatementItem attr_reader :category, :id, :time, :amount def initialize(item) case item when Order initialize_with_order(item) when Transaction initialize_with_transaction(item) end end def valid? !(@category && @id && @time && @amount).nil? end private def initialize_with_order(order) return nil if order.status != 'completed' @category = 'order' @id = order.id @time = order.updated_at @amount = order.price end def initialize_with_transaction(transaction) @category = transaction.category @id = transaction.id @time = transaction.updated_at @amount = transaction.amount end end 
+2
Jan 05 '16 at 3:33
source share

You can use the konstructor gem to declare multiple constructors in Ruby and simulate overloading:

 class Person def initialize(name) @name = name end konstructor def from_two_names(first_name, last_name) @name = first_name + ' ' + last_name end end Person.new('John Doe') Person.from_two_names('John', 'Doe') 
0
Jan 26 '17 at 7:07 on
source share

I usually do:

 class Person attr_reader :name def initialize(first: nil, last: nil) @name = [first, last].compact.join(' ') end end Person.new(first: 'ya').name # => "ya" Person.new(first: 'ya', last: 'ku').name # => "ya ku" 
0
Aug 18 '17 at 6:48
source share



All Articles