Ruby標準ライブラリのDigestでの const_missing の用法

Digestには何があったかなと思って、ruby/ext/digestを見てみたら、lib/digest.rbに以下のようなコードあった。Rubyハッシュ関数として、MD5SHA1、SHA2、RDM160というのなんかをサポートしてる。BubbleBabbleというマイナーなものも入ってるらしい。で、これらはCでモジュール化されていて、呼ばれたときに初めてロードされる。というのが、以下のコード。Digetst::Hoge.newなどとすると、libにHogeが入っていれば、require される。

require 'digest.so'

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

なんだか分からなかったのは、::Digest::Class というクラス。

module Digest
  :
  class ::Digest::Class
    # creates a digest object and reads a given file, _name_.
    #
    #   p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
    #   # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
    def self.file(name)
      new.file(name)
    end

    # Returns the base64 encoded hash value of a given _string_.  The
    # return value is properly padded with '=' and contains no line
    # feeds.
    def self.base64digest(str, *args)
      [digest(str, *args)].pack('m0')
    end
  end

コメントを読んでもピンと来なかったけど、これは、

module Digest
  class SHA2 < Digest::Class

などと継承が前提の、ほとんど中身のないクラスだった。クラスメソッドとして、Digest.fileを定義して、それをインスタンスメソッドに渡すような役割りをしている。DigestはCとRubyが入り混じっていて、ぼくには読むのが難しい。