Require的范围
The scope of Require
我在访问我在另一个文件中声明的模块时遇到问题,我想知道我在概念上是否有这个权利。让我解释一下。
如果我像这样设置文件 a、b 和 c
档案一
module HelloWorld
def greet
"hello world"
end
end
文件 b
require "a"
文件 c
require "b"
include HelloWorld
puts greet
所以是 a -> b -> c
,这行得通吗?
现在如果我这样做会怎样
档案一
module HelloWorld
def greet
"hello world"
end
end
文件 b
include HelloWorld
puts greet
文件 c
require "a"
require "b"
这会改变什么吗?在我看来,gems - 一旦需要 - 无论什么文件都可以访问,但在第二种情况下我无法访问模块。感谢任何帮助。
更新:我测试了这两种情况,它们都有效,这让我相信这不是概念问题,而是我的代码中的错误。我将开始调试项目。
当我尝试 运行 您的代码时,我收到以下错误消息
$ ruby c.rb
~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- a (LoadError)
from /Users/Sonna/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from c.rb:2:in `<main>'
简单来说就是使用了Kernel's require method
它找不到 a.rb
文件,然后引发 LoadError
异常。
为了获取文件,您可以使用 Kernal's require_relative
method
require_relative "a"
require_relative "b"
并且它将 a
和 b
文件相对于 c
文件。
或者您可以将以下代码行添加到您的 c.rb
文件中,这是一个
Ruby Gems 中使用的通用约定来加载其自定义 scripts/libraries
current_directory = File.expand_path("../", __FILE__)
$LOAD_PATH.unshift(current_directory) unless $LOAD_PATH.include?(current_directory)
这将从当前文件 __FILE__
添加当前目录 ../
,
将其扩展为所述当前目录的绝对路径并将其添加到
现有的加载路径全局变量;例如
puts $LOAD_PATH
# => ["~/Projects/ruby/Whosebug_questions/the_scope_of_require",
# "/usr/local/Cellar/rbenv/1.0.0/rbenv.d/exec/gem-rehash",
# "~/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0/x86_64-darwin15",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin15",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby",
# "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/x86_64-darwin15"]
require
内部使用按文件名查找,如果没有给出
绝对路径
If the filename does not resolve to an absolute path, it will be searched for
in the directories listed in $LOAD_PATH ($:)
.
所以当我运行你再次编码时,我看到了以下内容
$ ruby c.rb
hello world
需要注意的是
A file will not be loaded again if its path already appears in $"
. For
example, require 'a'; require './a'
will not load a.rb
again.
因此只要您的 require
方法之一在其中的方法之一之前出现一次
该文件被调用,它应该工作;所以你的两个例子都会起作用(如
只要将 sit 目录添加到 $LOAD_PATH
或者您使用
require_relative
代替)
我在访问我在另一个文件中声明的模块时遇到问题,我想知道我在概念上是否有这个权利。让我解释一下。
如果我像这样设置文件 a、b 和 c
档案一
module HelloWorld
def greet
"hello world"
end
end
文件 b
require "a"
文件 c
require "b"
include HelloWorld
puts greet
所以是 a -> b -> c
,这行得通吗?
现在如果我这样做会怎样
档案一
module HelloWorld
def greet
"hello world"
end
end
文件 b
include HelloWorld
puts greet
文件 c
require "a"
require "b"
这会改变什么吗?在我看来,gems - 一旦需要 - 无论什么文件都可以访问,但在第二种情况下我无法访问模块。感谢任何帮助。
更新:我测试了这两种情况,它们都有效,这让我相信这不是概念问题,而是我的代码中的错误。我将开始调试项目。
当我尝试 运行 您的代码时,我收到以下错误消息
$ ruby c.rb
~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- a (LoadError)
from /Users/Sonna/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from c.rb:2:in `<main>'
简单来说就是使用了Kernel's require method
它找不到 a.rb
文件,然后引发 LoadError
异常。
为了获取文件,您可以使用 Kernal's require_relative
method
require_relative "a"
require_relative "b"
并且它将 a
和 b
文件相对于 c
文件。
或者您可以将以下代码行添加到您的 c.rb
文件中,这是一个
Ruby Gems 中使用的通用约定来加载其自定义 scripts/libraries
current_directory = File.expand_path("../", __FILE__)
$LOAD_PATH.unshift(current_directory) unless $LOAD_PATH.include?(current_directory)
这将从当前文件 __FILE__
添加当前目录 ../
,
将其扩展为所述当前目录的绝对路径并将其添加到
现有的加载路径全局变量;例如
puts $LOAD_PATH
# => ["~/Projects/ruby/Whosebug_questions/the_scope_of_require",
# "/usr/local/Cellar/rbenv/1.0.0/rbenv.d/exec/gem-rehash",
# "~/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0/x86_64-darwin15",
# "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin15",
# "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby",
# "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0",
# "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/x86_64-darwin15"]
require
内部使用按文件名查找,如果没有给出
绝对路径
If the filename does not resolve to an absolute path, it will be searched for in the directories listed in
$LOAD_PATH ($:)
.
所以当我运行你再次编码时,我看到了以下内容
$ ruby c.rb
hello world
需要注意的是
A file will not be loaded again if its path already appears in
$"
. For example,require 'a'; require './a'
will not loada.rb
again.
因此只要您的 require
方法之一在其中的方法之一之前出现一次
该文件被调用,它应该工作;所以你的两个例子都会起作用(如
只要将 sit 目录添加到 $LOAD_PATH
或者您使用
require_relative
代替)