2012-10-17 99 views
8

用Ruby 1.9.3開始,我們可以創建私有常量:Module.private_constant做什麼?有沒有辦法只列出私人常量?

module M 
    class C; end 
    private_constant :C 
end 

是否有什麼這個沒有一個良好的文檔?有沒有辦法只獲得私人常量的名字,類似於調用constants

+0

請解釋你計劃得到的這個用途。 –

+0

Ruby沒有私有常量。你可以得到最接近的是一個類變量,但這不是非常私人的,因爲它與所有的子類共享。 – Linuxios

+0

@RyanBigg我沒有任何用處。我不明白你的問題與我的問題的相關性。 – sawa

回答

3

隨着Ruby 2.1的,而Module#constants僅包括公共常量,如果設置inherit=false,你會得到私人常數爲好。所以如果你在constants(false)找到一個常量,但在constants找不到常量(並且你不關心繼承的常量),那麼這可能是一種或多或少的可靠的方式來判斷它是否是私有的。

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] 

這是無證,我不知道這是否是故意的,但經驗很有效。我會用單元測試來支持它。


更新:它看起來這是a bug in Ruby,並在未來的版本中可能會消失。

+1

謝謝。我不知道。但是這看起來很奇怪。這可能是一個Ruby的錯誤。 – sawa

+1

我做了一個,但報告:https://bugs.ruby-lang.org/issues/12345。 – sawa

+1

@sawa看起來錯誤被接受。我更新了答案。 –

9

直到Ruby 1.9.3纔有私人常量。要獲得所有常量的列表,可以簡單地使用#constants

module Mod 
    CONST = "value" 
end 

Mod.constants #=> [:CONST] 

從1.9.3,.private_constant加入,但沒有什麼是真正的私有,你可以做...

module Mod 
    CONST = "value" 
    private_constant :CONST 
end 

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

我不認爲是獲得列表的方式所有的私人常量,但你仍然可以測試一個特定名稱的存在。

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

那麼下面的代碼是什麼意思? 'A類; B = 5; private_constant:B;結尾' – sawa

+1

隨着你的編輯,你的答案的後半部分與上半年相矛盾。 –

+0

這是因爲我寫了「在Ruby 1.9.3」而不是「直到Ruby 1.9.3」;-) – thoferon

相關問題