2017-10-12 61 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并明确加载每个库。