2017-10-12 64 views
1

我想知道如何以編程方式提前查看Digest模塊上可用的每個常量。下面看到的行爲是由於const_missing使用here顯示「摘要」中的所有常量

require 'digest' 

Digest.constants 
#=> [:Class, :REQUIRE_MUTEX, :Instance, :Base] 

Digest::MD5 
Digest.constants 
#=> [:Class, :REQUIRE_MUTEX, :Instance, :Base, :MD5] 

Digest::SHA1 
Digest.constants 
#=> [:Class, :REQUIRE_MUTEX, :Instance, :Base, :MD5, :SHA1] 

考慮到他們在可能的消化元編程,我怎麼能知道所有可能的可用摘要?

知識,出現在紅寶石2.4.1可用的那些應該是[:SHA256, :SHA384, :SHA512, :SHA1, :SHA2, :MD5, :RMD160]

+0

一種方法是查看源代碼:https://github.com/ruby/ruby/tree/trunk/ext/digest –

+0

除了此評論似乎另有說明: https://github.com/ ruby/ruby​​/blob/trunk/ext/digest/lib/digest.rb#L103 您可以加載不在源代碼中的SHA512。 – BookOfGreg

+1

好點。那麼,因爲常量是懶惰加載的,我不知道如何在不知道它們的情況下列出它們。 ¡\\ _(ツ)_ /¯ –

回答

0

下面是從當前master branch of ruby剪斷代碼:

module Digest 
    def self.const_missing(name) # :nodoc: 
    case name 
    when :SHA256, :SHA384, :SHA512 
     lib = 'digest/sha2.so' 
    else 
     lib = File.join('digest', name.to_s.downcase) 
    end 

    begin 
     require lib 
    rescue LoadError 
     raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1) 
    end 
    unless Digest.const_defined?(name) 
     raise NameError, "uninitialized constant Digest::#{name}", caller(1) 
    end 
    Digest.const_get(name) 
    end 

    # ... 
end 

...所以,你可以」如果不知道它們,真的列出所有常量!您需要require必要的文件,或者直接引用常量(這將動態加載文件,如上所示)。

我能給的任何解決方法解決方案只能保證適用於特定版本的ruby。不幸的是,你最好只使用read the documentation並明確加載每個庫。