【问题标题】:Display all constants in 'Digest'在“摘要”中显示所有常量
【发布时间】:2018-03-24 02:54:46
【问题描述】:

我想知道如何以编程方式提前查看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]

鉴于他们正在对可能的摘要进行元编程,我如何才能知道所有可能的可用摘要?

对于知识,Ruby 2.4.1 中似乎可用的应该是[:SHA256, :SHA384, :SHA512, :SHA1, :SHA2, :MD5, :RMD160]

【问题讨论】:

  • 一种方法是查看源代码:github.com/ruby/ruby/tree/trunk/ext/digest
  • 除非这条评论似乎另有说明:github.com/ruby/ruby/blob/trunk/ext/digest/lib/digest.rb#L103 并且您可以加载不在源代码中的 SHA512。
  • 好点。那么,由于常量是延迟加载的,我不知道如何在不知道它们的情况下列出它们。 ¯\_(ツ)_/¯
  • ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]$ irbrequire 'digest'#=> trueDigest.constants#=> [:Class, :REQUIRE_MUTEX, :Instance, :Base]Digest::SHA512Digest::SHA512#=> Digest::SHA512Digest.constants#=> [:Class, :REQUIRE_MUTEX, :SHA256, :SHA384, :SHA512, :Instance, :Base]s
  • 啊,我明白了。它是belongs to SHA2 family,在源代码中。

标签: ruby digest


【解决方案1】:

这是从当前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 并显式加载每个库!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-29
    • 2020-03-24
    • 1970-01-01
    • 2023-03-21
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多