我无法访问我在另一个文件中声明的模块,我想知道我是否在概念上有这个权利。让我解释一下。
归档
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"
这会改变什么吗?在我看来,宝石 - 一旦需要 - 无论什么文件都可以访问,但我在第二种情况下访问模块时遇到问题。任何帮助表示赞赏。
更新:我测试了两个场景,它们都有效,这让我相信这不是一个概念问题,而是我的代码中的一个错误。我打算调试项目。
答案 0 :(得分:1)
当我尝试运行您的代码时,我收到以下错误消息
$ 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
&amp;相对于b
文件的c
个文件。
或者您可以将以下代码行添加到c.rb
文件中,这是一个
Ruby Gems中用于加载其自定义脚本/库的常用约定
current_directory = File.expand_path("../", __FILE__)
$LOAD_PATH.unshift(current_directory) unless $LOAD_PATH.include?(current_directory)
这将从当前文件../
添加当前目录__FILE__
,
将它扩展为所述当前目录的aboslute路径并将其添加到
现有的Load Path全局变量; e.g。
puts $LOAD_PATH
# => ["~/Projects/ruby/stackoverflow_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
内部用于通过文件名查找的内容
绝对路径
如果文件名未解析为绝对路径,则会搜索该文件名 在
中列出的目录中$LOAD_PATH ($:)
。
所以,当我再次运行代码时,我会看到以下内容
$ ruby c.rb
hello world
应该注意
如果文件的路径已经显示在
$"
中,则不会再次加载该文件。对于 例如,require 'a'; require './a'
将无法再次加载a.rb
。
只要您的require
方法之一出现在其中一个方法之前,就会发生一次
该文件被调用,它应该工作;所以你的两个例子都可行(如
只要将sit的目录添加到$LOAD_PATH
或您使用
require_relative
代替)