require 'digest/md5' # => true
Digest::Md5.hexdigest('') # => "d41d8cd98f00b204e9800998ecf8427e"
这需要使用哪个文件?是否需要实际文件?还是以编程方式需要它?
Kernel#require
的文档中进行了解释:
要求(名称(→真或假
加载给定的
name
,如果成功则返回true
,如果成功则返回false
该功能已加载。如果文件名未解析为绝对路径,它将 在
如果$LOAD_PATH
($:
(中列出的目录中搜索。文件名的扩展名为".rb",则将其作为源文件加载;如果 扩展名为".so"、".o"或".dll",或默认共享库 扩展在当前平台上,Ruby 将共享库加载为 Ruby 外延。 否则,Ruby 会尝试将 ".rb"、".so" 等添加到 名称,直到找到。 如果找不到命名的文件,将引发加载错误。
默认情况下,$LOAD_PATH
将包含 Ruby 标准库所在的目录。Directories,复数形式,因为标准库中的原生(编译二进制(模块与纯 Ruby 模块位于不同的目录中。
Digest实际上是一个很好的例子,因为它的一些文件是原生的,而另一些是Ruby。
在我的Mac上,$LOAD_PATH
包括(除其他外(这两个目录(为便于阅读而截断(:
-
.../usr/lib/ruby/2.0.0
-
.../usr/lib/ruby/2.0.0/universal-darwin15
前者是纯 Ruby 模块所在的位置,后者是原生模块所在的位置。
因此,当我这样做require 'digest/md5'
Ruby首先在.../usr/lib/ruby/2.0.0/
中查找名为digest/
的目录,并在找到它后,在其中查找一个名为md5.rb
的文件。它找不到它,所以它寻找md5.bundle
.为什么.bundle
而不是.so
或.o
?因为这是 Ruby 在为 OS X 编译时配置的"默认共享库扩展"。
Ruby 在那里找不到它,所以接下来它看起来.../usr/lib/ruby/2.0.0/universal-darwin15/digest/
.那里没有md5.rb
,但有一个md5.bundle
,所以Ruby加载了它。
它加载了一个 C 扩展,可以在 Ruby 的源代码目录中找到 - ruby/ext/digest/md5/
它是 Ruby 的标准库 (stdlib( 之一,这意味着它几乎可以在 Ruby 的每个实现中使用。事实上,它确实加载了一个文件。但是它是在安装 Ruby 时复制到您的计算机的文件,并且几乎总是可供您使用。标准库的另一个很好的例子是 DateTime
。
当我开始学习Ruby和Rails时,有一件事让我感到困惑,那就是Rails需要相当数量的Ruby标准库。因此,最好了解引擎盖下实际发生的事情。