2014-01-11 5 views
7

Nehmen wir an, wir diese Ruby-Klasse haben:Wo sind die Singleton-Konstanten der Ruby-Klasse gespeichert?

class MyClass 
    class << self 
    MC_CONST = 30 
    end 
end 

Dann lassen Sie uns MyClass instanziiert und eine weitere Konstante auf die Metaklasse Objekt hinzufügen:

m = MyClass.new 
class << m 
    OBJ_MC_CONST = 50 
end 

Es gibt keine Probleme mit dem Objekt Singletons Konstante:

m.singleton_class::OBJ_MC_CONST # => 50 <-- [OK] 
m.singleton_class.constants.include? :OBJ_MC_CONST # => true <- [OK] 

Aber nicht genau das, was ich mit der Klasse Singleton Konstante erwarten würde:

MyClass.singleton_class::MC_CONST # => 30 <-- [OK] 
MyClass.singleton_class.const_get :MC_CONST # => 30 <-- [OK] 
MyClass.singleton_class.constants.include? :MC_CONST # => false <-- [Why???] 

Warum auf der Erde das Array von .constants Verfahren auf metaclass von MyClass Klasse zurückgegeben nicht enthalten: MC_CONST? Was fehlt mir hier?

Vielen Dank.


EDIT 1: Dies scheint doch ein Fehler in MRI 2.x zu sein. Ich habe ein neues Problem mit dem Ruby-Kernteam eingereicht: https://bugs.ruby-lang.org/issues/9413, um dies zu beheben.

EDIT 2: Dieser Fehler wurde in https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/44628/diff/

Antwort

5

fixiert offenbar wurde habe ich ein bisschen auf diese Frage untersucht, und ich denke, es wird durch einen Fehler/Inkonsistenz/Idiosynkrasie von MRI verursacht wird.

Im MRT 2.1.0, dieser Code:

class MyClass 
    class << self 
    MC_CONST = 30 
    end 
end 

p MyClass.singleton_class.const_defined? :ABBA_CONST, false 
p MyClass.singleton_class.const_defined? :MC_CONST, false 
p MyClass.singleton_class.constants(false) 

ergibt

false 
true 
[] 

So ist die MC_CONST Konstante definiert ist, aber es ist nicht verfügbar, da eine lokale Konstante der Klasse (I‘ Ich übergebe False an die verschiedenen Methoden, um die konstante Auflösung zu deaktivieren und behalte sie nur lokal für diese Klasse), was es auch sein sollte. Wenn wir auf die Dokumentation von Module#constants überprüfen heißt es:

Gibt ein Array mit den Namen der Konstanten zugänglich in mod. Diese enthält die Namen von Konstanten in beliebigen eingeschlossenen Modulen (Beispiel unter Anfang des Abschnitts), sofern der Parameter all nicht auf false gesetzt ist.

Siehe auch Modul :: const_defined?.

So sagt es uns const_defined? zu überprüfen, um das Verhalten von constants besser zu verstehen, aber die beiden Methoden geben unterschiedliche Ergebnisse!


Darüber hinaus funktioniert dieser Code auf andere Ruby-Implementierung wie erwartet.

Auf JRuby 1.7.9, es ergibt:

false 
true 
[:MC_CONST] 

Auf Rubinius 2.2.1, es ergibt:

false 
true 
[:MC_CONST] 

Welches ist das erwartete Verhalten :)

+0

Vielen Dank für die Eingabe. Im aktuellen MRI scheint ich ein Fehler zu sein. Ich habe ein neues Problem mit dem Ruby-Kernteam eingereicht. Ich werde die Beschreibung mit der Ausgabe-URL aktualisieren. – demisx

Verwandte Themen