2010-11-13 13 views
13

Ich möchte, dass eine geerbte Ruby-Klasse ihren Klassennamen über eine Klassenmethode "kennt". Dies wird am besten durch ein konstruiertes Beispiel illustriert:Klassenmethode, Klassenname in Ruby zu "wissen"?

class Parent 
    def self.whoami 
    ?? 
    end 
end 

class Child < Parent 
    #No code should be needed. 
end 

So soll ich in der Lage sein zu nennen:

Parent.whomai 

und erwartet eine Rückkehr des „Parent“ Ich soll dann anrufen kann,:

Child.whoami 

und erwarte eine Rückkehr von "Kind" Ich habe das Gefühl, dass dies in herkömmlichen Sprachen nicht möglich ist. Aber Rubys Metaprogrammierungsmodell hat mich schon früher erstaunt. Irgendwelche Gedanken? Danke im Voraus.

Antwort

20

A-Klasse ist ein Verfahren, in dem die Klasse der Empfänger, also das Objekt zu finden, auf das die Methode aufgerufen wird (was Sie zu versuchen, erscheinen hier zu tun) einfach den Wert von self inspizieren.

class Parent 
    def self.whoami 
    self 
    end 
end 

class Child < Parent 
end 

puts Parent.whoami #=> Parent 
puts Child.whoami #=> Child 
+0

Das schien viel zu einfach. Vielen Dank. –

+0

Was ist los mit ['Module # name'] (http://Ruby-Doc.Org/ruby-1.9/classes/Module.html#M000913) und warum die doppelte' puts'? –

+1

Es gibt keinen Grund, eine Methode zu haben, die self zurückgibt und das Objekt direkt verwendet: 'puts Parent'. Puts ruft Parent.to_s hinter den Kulissen auf, um einen String-Namen der Klasse zu erhalten. –

2

Ist das nicht Parent.class wird Ihnen das sagen?

class Parent 
    def self.whoami 
    self.to_s 
    end 
end 

class Child < Parent 
end 

> Parent.whoami 
=> "Parent" 
> Child.whoami 
=> "Child" 
+0

Wenn sich eine Klassenmethode, 'self' wird die Klasse zurückkehren –

+2

Was mit [' Module # name'] falsch ist (http://Ruby-Doc.Org/ruby -1.9/Klassen/Module.html # M000913)? –

+0

@ Jörg Ich ging davon aus, dass er etwas komplizierter als eine Klassenmethode, die einen Namen zurückgegeben hat, aber Sie haben Recht, dass 'Modul # name' ist der richtige Weg, dies zu tun. –

15

Verfahren den Namen einer Klasse zu erhalten (Modul, tatsächlich) ist nur Module#name. Es gibt keine Notwendigkeit, Ihre eigenen zu schreiben:

Parent.name # => 'Parent' 
Child.name # => 'Child' 

, aber in Ruby, es ist wirklich nicht so etwas wie ein „Klassenname“ ist, wie es in einigen anderen Sprachen ist. In Ruby ist eine Klasse einfach ein Objekt wie jedes andere Objekt, das wie jede andere Variable einer Variablen zugewiesen wird.

Alle Module#name Methode ist Schleife durch alle Konstanten im System und prüfen, ob das Modul zu einer von ihnen zugewiesen wurde, und geben Sie den Namen dieser Konstante oder nil, wenn es keine finden kann.

Also, genau wie jedes andere Objekt ist der "Name" einer Klasse wirklich nichts als jede Variable, die Sie verwenden, um darauf zu verweisen.

Beispiel:

foo = Class.new 
foo.name # => nil 

nun der "Name" der Klasse ist foo. Module#name gibt jedoch nil zurück, da foo keine Konstante ist.

bar = foo 
bar.name # => nil 

nun der "Name" der Klasse ist sowohlfoo und bar, aber Module#name offenbar noch zurück nil.

BAZ = foo 
foo.name # => 'BAZ' 

Nun, da die Klasse zu einer Konstante zugewiesen wurde, die konstant Name wird ist das Klassennamen & hellip betrachtet werden;

BAZ = nil 
foo.name # => 'BAZ' 

& hellip; selbst nachdem die Konstante etwas anderem zugeteilt wurde und & hellip;

QUX = foo 
QUX.name # => 'BAZ' 

& hellip; selbst nachdem die Klasse einer anderen Konstante zugewiesen wurde.

Module#to_s verwendet Module#name wenn es nicht nil ist, so, den Namen einer Klasse zu drucken, können Sie einfach tun

puts Parent 

Es gibt wirklich absolut keine Notwendigkeit für die ganze komplexe Flusen in den anderen Antworten.

1

Sie Klasse Angenommen:

class ABC 
def self.some_method 
    self.name #it will return 'ABC' 
    self.name.constantize #it will return ABC 
end 
end 
Verwandte Themen