2011-01-06 14 views
1

ich mit Funktionsdefinitionen vertraut bin und Variablendeklarationen in Klassendefinitionen sind:Was bedeutet Methodenklasse in der Klassendefinition in Ruby?

public class MyClass { 
    public int myvar; 
    public void doSomething() { 

    } 
} 

Aber was bedeutet es „bedeutet“ in Ruby, wenn eine Methode tatsächlich in der Klassendefinition genannt wird? Dies geschieht reichlich in Rails, zum Beispiel:

class User < ActiveRecord::Base 
    has_many :posts 
end 

Was genau dies zu tun hat (auf einem niedrigeren Niveau als „es einige Methoden zur Klasse fügt hinzu“)? Wie würde ich eine solche Funktion implementieren (z. B. eine, die einige zusätzliche Methoden mischt)?

+0

Ich vermute, aber ich bin mir nicht sicher, dass einige Sprachen Code haben, der zur Kompilierzeit läuft und Code, der zur Laufzeit läuft. Ich denke Ruby läuft in der Regel zur Laufzeit. –

Antwort

2

Während die Definition einer Klasse ist der Empfänger das Klassen-Objekt, und es ist so wirklich über die gleiche Sache wie die bekannteren Klasse.Methode Technik zum Aufruf einer Klassenmethode.

Also, um die ClassName.new Analogie ein bisschen weiter zu tragen, können Sie jede Klassenmethode auf diese Weise aufrufen. Lassen Sie uns new als Beispiel:

>> class C 
>> def happy 
>>  puts 'new year' 
>> end 
>> new 
>> end.happy 
new year 
=> nil 

BTW, kann nicht durch die Tatsache verwirrt, dass diese Methode in der übergeordneten Klasse definiert ist. F: Was ist der Unterschied zwischen Ihrer abgeleiteten Klasse und Ihrer Superklasseninstanz? Sag ActiveRecord::Base? A: Nichts! Es gibt nur die eine Klasseninstanz.

+0

Danke! Ich habe anhand Ihres Beispiels festgestellt, dass "Welt" nicht zweimal gedruckt wurde, als Sie "B" deklarierten. Ist es richtig abzuleiten, dass beim Erweitern einer Klasse die Methodenaufrufe in der Klassendefinition nicht angewendet werden (ich würde annehmen, dass Methodenaufrufe wie 'has_many 'tatsächlich die Klassendefinition zur Laufzeit ändern und damit effektiv' geerbt 'werden Ausmaß, obwohl)? Irgendwelche zusätzlichen Seltsamkeit sollte ich beachten? –

+0

has_many ändert Daten, die in der Model-Klasse gespeichert sind. Die modifizierten Datenstrukturen sind in ActiveRecord :: Base oder anderen bereits gemischten Modulen definiert. Sie sollten sich den Quellcode in A/R ansehen, es gibt viel Mischungskühle in Rails – ffoeg

+1

Sicher, aber ich denke nicht Das OP fragte wirklich genau, was Rails tut, was sicherlich eine Menge Metaprogrammierungsmagie beinhaltet.Ich meine, das OP hat speziell gefragt: "Wie würde ich eine solche Funktion implementieren?". Nun, das ist die Antwort auf genau diese Frage. – DigitalRoss

1

ActiveRecord :: Base definiert die Klassenmethode has_many. Mit Ruby können Sie Superklassenklassenmethoden während der Definition einer Unterklasse aufrufen.

Sie können dies selbst tun, Ihre eigene Klasse Methoden zu Activerecord :: Base oder Ihre eigene Klasse hinzufügen, indem Sie ein Modul macht in Ihnen mischen

Ein einfaches Beispiel dafür, wie dies selbst zu tun.

module MyMixin 
    def self.included(base) 
    base.extend ClassMethods # Load class methods 
    super 
    end 
    module ClassMethods 
    def hello 
     puts "MyMixin says => Hello World" 
    end 
    end 
end 
ActiveRecord::Base.send :include, MyMixin 
Verwendung

Beispiel:

class MyRecord < ActiveRecord::Base 
    hello 
end 

Anheizen Rails Sie sehen würden, dies auf der Konsole ausgegeben:

MyMixin says => Hello World 
+1

Dies ist eine gute Antwort, aber ich wundere mich über * "Ruby können Sie Superklassen Klassenmethoden während der Definition einer Unterklasse aufrufen". * Ich glaube nicht, dass das völlig richtig ist. Der Empfänger ist die Klasse, die Sie definieren. Sie rufen Klassenmethoden Ihrer eigenen Klasse auf, und dazu gehören Methoden, die von der Oberklasse übernommen wurden. – DigitalRoss

+0

vielleicht ist der Wortlaut über vereinfacht. Wollte nicht wirklich in eine lange Diskussion über die Bedeutung von "Selbst" hineingezogen werden – ffoeg