Die Antwort ist sowohl Ja als auch Nein.
Sie können das gleiche Ergebnis wie in anderen Sprachen erzielen, indem Sie verschiedene Mechanismen verwenden, darunter:
- Standardwerte für Argumente
- Variablenargumentlisten (Der Splat-Operator)
- Definieren Sie Ihr Argument als Hash
Die tatsächliche Syntax der Sprache erlaubt es Ihnen nicht, eine Methode zweimal zu definieren, selbst wenn die Argumente unterschiedlich sind.
In Anbetracht der drei oben genannten Optionen können diese anhand Ihres Beispiels wie folgt implementiert werden
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"]
name = name + " " + args["lastName"] unless args["lastName"].nil?
@name = name
end
end
class Person
def initialize(*args)
end
end
Sie werden häufig auf den zweiten Mechanismus in Ruby-Code stoßen, insbesondere in Rails, da er das Beste aus beiden Welten bietet und es syntaktischem Zucker ermöglicht, hübschen Code zu erzeugen, insbesondere, wenn der übergebene Hash nicht in geschweifte Klammern eingeschlossen werden muss.
Dieser Wikibooks-Link bietet weitere Informationen
Person.new(:first_name => "...", :last_name => "...")
Methode. Aus irgendeinem Grund kam es mir nicht in den Sinn, das zu benutzen, aber das beantwortet meine Frage.Ich neige dazu zu tun
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
Aber ich weiß nicht, ob dies der beste Ansatz ist.
quelle
class Person def initialize(name, lastName = nil) name = name + " " + lastName unless lastName.nil? @name = name end end
quelle
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
quelle
Sie können den Double-Splat-Operator
**
in Verbindung mit logischen oder (Double-Pipes)||
innerhalb derinitialize
Methode verwenden, um den gleichen Effekt zu erzielen.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">
Wenn jedoch eine neue
Person
ohne a erstellt wirdfirst_name
, schlägt der Append-<<
Vorgang mit fehlNoMethodError: undefined method '<<' for nil:NilClass
. Hier ist eine überarbeiteteinitialize
Methode, um diesen Fall zu behandeln (Verwendenstrip
zum Entfernen von Leerzeichen, wenn eine der beiden Optionen ausgeschlossen ist).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">
Tatsächlich behandelt dieser Ansatz den Aufruf
Person.new
ohne Argumente oder mit einem unerwarteten Schlüssel, um die neue Instanz mit@name
set auf eine leere Zeichenfolge zurückzugeben:nameless = Person.new #=> <#Person @name=""> middle_malcom = Person.new(middle_name: 'Malcom') #=> <#Person @name="">
quelle
Kasse funktional-rubinroter Edelstein, der von Elixir- Muster-Matching- Funktionen inspiriert ist.
class Person include Functional::PatternMatching defn(:initialize, String) { |name| @name = name } defn(:initialize, String, String) {|first_name, last_name| @name = first_name + ' ' + last_name } end
quelle
Person
,first_name
undlast_name
.Sie können konstructor gem verwenden, um mehrere Konstruktoren in Ruby zu deklarieren und eine Überladung zu imitieren:
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')
quelle