2016-10-25 1 views
4

Werfen wir einen normalen Rubin Klasse nehmen:Ruby-Klasse-Instanzmethode def initialize: Instanz oder Klassenmethode?

class Person 
    attr_accessor :name 
    def initialize name 
    @name = name 
    end 
end 

bob = Person.new("bob") 

Meine Frage ist die Natur der initialize. Hier ist die Sache, new ist eindeutig eine Klassenmethode, aber mir scheint, dass initialize ist eine Instanz-Methode (nicht Klasse), die für die Instanz aufgerufen wird, wenn die Klassenmethode new aufgerufen wird.

Habe ich das richtig? Oder kann jemand neues Licht schütten? Ich habe einige Google-Suchen durchgeführt und konnte keine Klarheit finden.

+1

ist es irgendwie einzigartig - Sie können auf den Bereich der Instanzmethode zugreifen, aber wie Sie sagen, ist es wie eine Klassenmethode aufrufbar. Beachten Sie, dass initialize nicht aufgerufen wird, wenn Sie 'def self.new' definieren. –

+0

bedeutet das, dass es aufgerufen wird, weil die 'neue' Methode aufgerufen wird? oder ist es in der Tat die 'neue' Methode? –

+0

Ja. Beachten Sie auch, dass [Modul # attr_accessor] (http://ruby-doc.org/core-2.0.0/Module.html#method-i-attr_accessor) ebenfalls eine Klassenmethode ist, die zwei Instanzmethoden (hier 'name') erzeugt und 'name ='). –

Antwort

3

Dann wird ein neues Objekt initialisiert wird (das heißt, wenn Sie new auf eine Klasse nennen) das ist, was effektiv diese Methode aufgerufen wird, ist:

class Class 
    def new(*args, &block) 
    obj = allocate 
    obj.send(:initialize, *args, &block) 
    obj 
    end 
end 

In der Standard-Ruby-Implementierung wird diese Methode implementiert in C ist aber well documented.

Um zu verstehen, was hier passiert, müssen Sie beachten, dass in Ruby sogar Klassen Objekte sind (sie sind Instanzen oder die Klasse Class). Wenn Sie also new in Ihrer Klasse Person aufrufen, rufen Sie tatsächlich die new-Methode für die Instanz eines Class-Objekts auf.

Wie Sie sehen können, bietet die Klasse Person eine Methode zum Zuweisen von Speicher für die neue Instanz. Nachdem der Speicher zugewiesen wurde, ruft die new-Methode initialize auf der neu erstellten Instanz auf.

+0

das Code-Snippet ist perfekt, danke –

+0

In der Realität ist 'initialize' standardmäßig' private', also ist die mittlere Zeile * wirklich * mehr wie 'obj.send (: initialize, * args, & block)', aber die Endergebnis ist das gleiche. Wenn Sie jemals Objective-C verwendet haben, sollte Ihnen das bekannt vorkommen, denn 'Foo.alloc.init' ist im Wesentlichen wie Sie ein Objekt erstellen. –

+0

Danke @ JörgWMittag. Ich habe den Code korrigiert und etwas mehr darüber gelernt, wie die Methodenverteilung in C-Ruby funktioniert. –

Verwandte Themen