require 'digest/md5' 是如何工作的?
How does require 'digest/md5' works?
require 'digest/md5' # => true
Digest::Md5.hexdigest('') # => "d41d8cd98f00b204e9800998ecf8427e"
这个需要用到哪个文件?是否需要实际文件?还是以编程方式需要?
它加载了一个 C 扩展,可以在 Ruby 的源目录中找到 - ruby/ext/digest/md5/
这在 documentation for Kernel#require
:
中有(大致)解释
require(name) → true or false
Loads the given name
, returning true
if successful and false
if
the feature is already loaded.
If the filename does not resolve to an absolute path, it will be
searched for in the directories listed in $LOAD_PATH
($:
).
If the filename has the extension “.rb”, it is loaded as a source file; if
the extension is “.so”, “.o”, or “.dll”, or the default shared library
extension on the current platform, Ruby loads the shared library as a Ruby
extension. Otherwise, Ruby tries adding “.rb”, “.so”, and so on to the
name until found. If the file named cannot be found, a LoadError will be raised.
默认情况下 $LOAD_PATH
将包含 Ruby 的标准库所在的目录。 Directories,复数形式,因为标准库中的原生(编译二进制)模块与 pure-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 编译时配置的 "default shared library extension"。去图。
Ruby 在那里找不到它,所以接下来它会在 .../usr/lib/ruby/2.0.0/universal-darwin15/digest/
中查找。那里没有 md5.rb
,但是 是 一个 md5.bundle
,所以 Ruby 加载它。
它是 Ruby 的标准库 (stdlib) 之一,这意味着它几乎在 Ruby 的每个实现中都可用。事实上,它确实加载了一个文件。但它是一个在您安装 Ruby 时复制到您的计算机的文件,并且几乎始终可供您使用。标准库的另一个很好的例子是 DateTime
。
当我开始学习 Ruby 和 Rails 时让我很困惑的一件事是 Rails 需要相当数量的 Ruby 标准库供您使用.因此,了解引擎盖下实际发生的事情是件好事。
require 'digest/md5' # => true
Digest::Md5.hexdigest('') # => "d41d8cd98f00b204e9800998ecf8427e"
这个需要用到哪个文件?是否需要实际文件?还是以编程方式需要?
它加载了一个 C 扩展,可以在 Ruby 的源目录中找到 - ruby/ext/digest/md5/
这在 documentation for Kernel#require
:
require(name) → true or false
Loads the given
name
, returningtrue
if successful andfalse
if the feature is already loaded.If the filename does not resolve to an absolute path, it will be searched for in the directories listed in
$LOAD_PATH
($:
).If the filename has the extension “.rb”, it is loaded as a source file; if the extension is “.so”, “.o”, or “.dll”, or the default shared library extension on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding “.rb”, “.so”, and so on to the name until found. If the file named cannot be found, a LoadError will be raised.
默认情况下 $LOAD_PATH
将包含 Ruby 的标准库所在的目录。 Directories,复数形式,因为标准库中的原生(编译二进制)模块与 pure-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 编译时配置的 "default shared library extension"。去图。
Ruby 在那里找不到它,所以接下来它会在 .../usr/lib/ruby/2.0.0/universal-darwin15/digest/
中查找。那里没有 md5.rb
,但是 是 一个 md5.bundle
,所以 Ruby 加载它。
它是 Ruby 的标准库 (stdlib) 之一,这意味着它几乎在 Ruby 的每个实现中都可用。事实上,它确实加载了一个文件。但它是一个在您安装 Ruby 时复制到您的计算机的文件,并且几乎始终可供您使用。标准库的另一个很好的例子是 DateTime
。
当我开始学习 Ruby 和 Rails 时让我很困惑的一件事是 Rails 需要相当数量的 Ruby 标准库供您使用.因此,了解引擎盖下实际发生的事情是件好事。