簡體   English   中英

如何通過反射獲取Ruby的Module類定義的常量?

[英]How do I get constants defined by Ruby's Module class via reflection?

我試圖讓Matz和Flanagan的“Ruby Programming Language”元編程章節進入我的腦海,但是我無法理解我夢想的以下代碼片段的輸出:

p Module.constants.length           # => 88
$snapshot1 = Module.constants       
class A
  NAME=:abc

  $snapshot2 = Module.constants
  p $snapshot2.length               # => 90
  p $snapshot2 - $snapshot1         # => ["A", "NAME"]

end
p Module.constants.length           # => 89
p Module.constants - $snapshot1     # => ["A"]
p A.constants                       # => ["NAME"]

本書指出類方法constants返回類的constants列表(如A.constants的輸出中A.constants )。 當我遇到上述奇怪的行為時,我試圖獲取為Module類定義的常量列表。

A常量出現在Module.constants中。 如何獲取Module類定義的常量列表?

文檔陳述

Module.constants返回系統中定義的所有常量。 包括所有類和方法的名稱

由於AModule.constants繼承了它的實現,它在基類和派生類型中的表現如何?

p A.class               # => Class
p A.class.ancestors       # => [Class, Module, Object, Kernel]

注意:如果您使用的是Ruby 1.9, constants將返回符號數組而不是字符串。

好問題!

你的困惑是由於類方法的事實Module.constants隱藏實例方法Module#constantsModule

在Ruby 1.9中,通過添加可選參數解決了這個問題:

# No argument: same class method as in 1.8:
Module.constants         # ==> All constants
# One argument: uses the instance method:
Module.constants(true)   # ==> Constants of Module (and included modules)
Module.constants(false)  # ==> Constants of Module (only).

在上面的示例中, A.constants調用Module#constants (實例方法),而Module.constants調用Module.constants

在Ruby 1.9中,您希望調用Module.constants(true)

在Ruby 1.8中,可以在Module上調用實例方法#constants 您需要獲取實例方法並將其綁定為類方法(使用不同的名稱):

class << Module
  define_method :constants_of_module, Module.instance_method(:constants)
end

# Now use this new class method:
class Module
   COOL = 42
end
Module.constants.include?("COOL")  # ==> false, as you mention
Module.constants_of_module         # ==> ["COOL"], the result you want

我希望我能夠將1.9功能完全反向移植到1.8 for backports gem,但我想不出在Ruby 1.8中只獲取模塊常量的方法,不包括繼承的模塊。

編輯 :剛剛更改了官方文檔以正確反映這一點......

在Marc的回應之后,我不得不回到我的思考洞穴一段時間。 使用更多代碼片段進行修補,然后再進行更多操作。 最后,當Ruby的方法分辨率似乎有意義時,將其寫成博客文章,這樣我就不會忘記。

符號:如果A“A的本征

A.constants ,方法解析(請參閱我博客文章中的圖像以獲得視覺輔助)按順序查找以下位置

  • MyClass"Object"BasicObject" (單例方法)
  • Class (實例方法)
  • Module (實例方法)
  • Object (實例方法)和內核
  • BasicObject (實例方法)

Ruby找到實例方法Module#constants

Module.constants ,Ruby會查看

  • Module"Object"BasicObject" (單例方法)
  • Class (實例方法)
  • Module (實例方法)
  • Object (實例方法)和內核
  • BasicObject (實例方法)

這次,Ruby在Module".constants找到了singleton / class方法,正如Marc所說。

模塊定義了一個影響實例方法的單例方法。 單例方法返回所有已知常量,而實例方法返回當前類及其祖先中定義的常量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM