2012-10-17 10 views
8

Beginnend in Ruby 1.9.3, können wir private Konstanten erstellen:Was macht Module.private_constant? Gibt es eine Möglichkeit, nur private Konstanten aufzulisten?

module M 
    class C; end 
    private_constant :C 
end 

Gibt es eine gute Dokumentation über das, was das bedeutet? Gibt es eine Möglichkeit, die Namen von nur privaten Konstanten zu erhalten, die dem Aufruf ähnlich sind constants

+0

Bitte erklären Sie, welche Verwendung Sie planen, zu erhalten. –

+0

Ruby hat keine privaten Konstanten. Der nächste, den Sie bekommen können, ist eine Klassenvariable, aber das ist nicht besonders privat, da es mit allen Unterklassen geteilt wird. – Linuxios

+0

@RyanBigg Ich habe keine Verwendung dafür. Ich verstehe die Relevanz Ihrer Frage zu meiner Frage nicht. – sawa

Antwort

3

Wie von Ruby 2.1, während Module#constants nur öffentliche Konstanten enthält, wenn Sie inherit=false gesetzt ist, wird man auch privat Konstanten erhalten. Wenn Sie also eine Konstante in constants(false) finden, aber nicht in constants (und Sie nicht über vererbte Konstanten Pflege), das könnte eine mehr oder weniger zuverlässige Art und Weise zu sagen, wenn es privat ist.

class Module 
    def private_constants 
    constants(false) - constants 
    end 
end 

module Foo 
    X = 1 
    Y = 2 
    private_constant :Y 
end 

puts "Foo.constants = #{Foo.constants}" 
puts "Foo.constants(false) = #{Foo.constants(false)}" 
puts "Foo.private_constants = #{Foo.private_constants}" 

# => Foo.constants = [:X] 
# => Foo.constants(false) = [:X, :Y] 
# => Foo.private_constants = [:Y] 

Dies ist nicht dokumentiert, und ich bin nicht sicher, ob es Absicht ist, aber es funktioniert empirisch. Ich würde es mit Unit-Tests untermauern.


Update: Es sieht aus wie diese a bug in Ruby ist, und in einer zukünftigen Version verschwinden.

+1

Danke. Das wusste ich nicht. Aber das sieht komisch aus. Es könnte ein Ruby-Bug sein. – sawa

+1

Ich habe einen Bericht erstellt: https://bugs.ruby-lang.org/issues/12345. – sawa

+1

@sawa Sieht so aus, als wäre der Fehler akzeptiert worden. Ich habe die Antwort aktualisiert. –

9

Es gibt keine privaten Konstanten bis Ruby 1.9.3. Um eine Liste aller Konstanten zu erhalten, können Sie einfach #constants verwenden.

module Mod 
    CONST = "value" 
end 

Mod.constants #=> [:CONST] 

Von 1.9.3, .private_constant wurde hinzugefügt, aber nichts wirklich privat ist, können Sie tun ...

module Mod 
    CONST = "value" 
    private_constant :CONST 
end 

Mod.const_get(:CONST) #=> "value" 

Ich glaube nicht, gibt es eine Möglichkeit, eine Liste des Erhaltens von die ganze private Konstante, aber Sie können immer noch die Anwesenheit eines bestimmten Namens testen.

Mod.const_defined?(:CONST) #=> true 
+0

Was bedeutet der folgende Code? 'Klasse A; B = 5; Privat_Konstant: B; Ende' – sawa

+1

Mit Ihrer Bearbeitung widerspricht die zweite Hälfte Ihrer Antwort der ersten Hälfte. –

+0

Das liegt daran, dass ich "in Ruby 1.9.3" anstelle von "bis Ruby 1.9.3" geschrieben habe ;-) – thoferon