2016-12-05 3 views
1

Ich bin nicht sicher, wo ich das gesehen habe, oder wenn ich nur denke, dass ich es gesehen habe, aber ich würde gern eine Methode aufrufen können, die eine Instanz einer Klasse mit dem gleichen Namen erstellt. Anstatt also:Wie definiere ich in Ruby eine Klassenkonstruktormethode mit demselben Namen wie die Klasse?

# The class is called 'Vector3', for example: 
Vector3.new(x,y,z) 

Ich möchte eine gleichnamige Methode haben, die die Klasse instanziiert, etwa so:

Vector3(x,y,z) #<- returns instance of Vector3 class 

Wie würden Sie festlegen, dass in Ruby?

+1

Sie könnten theoretisch eine Methode 'Vector3' definieren, die ein Alias ​​von' Vector3.new' im 'Kernel'-Modul ist, aber warum? –

+0

Wie würden Sie in Ruby eine Methode namens 'foo' definieren? Wie würden Sie dann eine Methode namens "Vector3" in Ruby definieren? –

Antwort

2

AFAIK können Sie nicht. Sie können etwas ähnliches tun, Vector3[x, y, z].

Beachten Sie, dass die Ruby-Bibliothek dieses Gerät ebenfalls verwendet. Es gibt Hash.new(...) und Hash[...] , aber keine Hash(...). Diese Parallelen wie Proc Objekte aufgerufen werden:

greet = Proc.new { |name| puts "Hello, #{name}" } 
greet["Amadan"] 

EDIT: Ich stehe korrigiert:

module Kernel 
    def Vector3(*args) 
    Vector3.new(*args) 
    end 
end 

Aber, wie Eli Sadoff sagte, ist es nicht praktikabel, verletzt Verkapselung und Ruby-Stil (Funktionen und Methoden sollte Kleinbuchstaben sein).

+3

Das stimmt nicht wirklich. Sie können 'def Vector3 (x, y, z); Vector3.new (x, y, z); Ende 'im Modul' Kernel ', aber es ist nicht praktikabel. –

+0

Nun, das ist eine schöne Lösung, danke! Ich werde nur das verwenden (Ihre ursprünglich vorgeschlagene Lösung, das ist). – mydoghasworms

+0

@EliSadoff Ist es möglich, eine Modulmethode und eine Klasse mit demselben Namen im Modul zu haben, um dies als Alternative zu erreichen? – mydoghasworms

4

Wie @Eli erwähnt, können Sie eine Methode im Kernel definieren:

def Kernel.Vector3(*args) 
    Vector3.new(*args) 
end 

Rubin tut dies für Array, Complex, Float, Hash, Integer, Rational und String wo Sie wahrscheinlich es sah.

Der Grund, es funktioniert ist, dass ObjectKernel enthält, damit alle Objekte in Ihrem Programm (ausgenommen diejenigen, direkt von BasicObject vererben) wird diese Methode haben.

Dies ist jedoch unidiomatisch, unnötig (Sie verwirren alle Objekte mit einer zusätzlichen Methode), verwirrend (Großbuchstaben sollten Konstanten sein) und allgemein herabgesehen.

+1

Danke. Ich gehe mit Amadans Antwort, denn der allgemeine Konsens scheint zu sein, dass die Kernel-Route eine schlechte Idee ist. Die Array-Syntax ist immer noch schön und prägnant. – mydoghasworms

0

Dies beantwortet, was ich die Frage aus dem Titel verstanden habe. (Irgendwie übersah ich das Beispiel, das dem widerspricht.) Ich werde meine Antwort verlassen, weil ich denke, dass sie einige interessante Elemente enthält.

class MyClass 
    def hi 
    "hi" 
    end 
    my_alias = to_s 
    singleton_class.class_eval { alias_method(my_alias, :new) } 
end 

MyClass.methods(false) 
    #=> [:MyClass] 
my_instance = MyClass.MyClass 
    #=> #<MyClass:0x007fadc2092320> 
my_instance.hi 
    #=> "hi" 

Beachten Sie, dass dies funktioniert, wenn der Alias ​​new Argumente und/oder einen Block übergeben wird.

Siehe Object#singleton_class und Module#class_eval.

+0

@DorianG, warum hast du deine Frage gelöscht? Ich wollte gerade eine Antwort schreiben. Bitte erwägen Sie es wiederherzustellen. –

Verwandte Themen