我试图理解在ruby中导入文件是如何工作的,但是我几乎花了一整天的时间来弄明白为什么我可以在我的类中调用DateTime.now
,而我没有调用require 'date
。这些都是在docker容器示例上运行的,在那里我得到了ruby 3. 0. 3,让我卡住的是,当我试图在一个新的docker容器示例ruby 3. 0. 3上创建一个新的ruby文件时。尝试调用DateTime.now
,但它不起作用。
我试着在项目中查找包含date一词的require语句,在该项目中我可以调用DateTime.now
,但没有找到。
项目的gem文件,可以在其中调用DateTime而无需require语句
gem 'aws-sdk-s3', '~> 1.93'
gem 'mime-types'
gem 'optparse', '~> 0.1.0'
group :development do
gem 'rubocop', '~> 1.12'
end
group :test do
gem 'rspec', '~> 3.10'
gem 'rubocop-rspec', '~> 2.2'
gem 'webmock', '~> 3.12'
end
新项目的gem文件,在该文件中,如果没有require语句,我就无法调用DateTime
gem 'mime-types'
gem 'optparse', '~> 0.1.0'
gem 'gqli'
group :development do
gem 'rubocop', '~> 1.12'
end
group :test do
gem 'rspec', '~> 3.10'
gem 'rubocop-rspec', '~> 2.2'
gem 'webmock', '~> 3.12'
gem 'test-unit', '~> 3.0'
end
唯一的区别是两个项目中的aws和gqli,但我尝试让它们都有相同的gem文件,它仍然不工作。
1条答案
按热度按时间gab6jxml1#
当您
require
aws-sdk-s3
library(它是aws-sdk-s3
Gem库的一部分)时,require
又是aws-sdk-core
库:aws-sdk-core
library是aws-sdk-core
Gem的一部分,它又使用Kernel#require_relative
加载param_converter
library,如下所示:然后,
param_converter
库依次加载date
库:aws-sdk-core
Gem不依赖于date
Gem:但是你不必依赖
date
Gem来使用date
library,因为date
Gem是default Gem,这意味着它是Ruby标准库的一部分,由Ruby开发人员维护,不需要安装,不需要列为Gem依赖项,也不需要激活。这就是为什么您不必亲自对
date
库执行require
操作的原因:因为require
是一个库,而require
又是另一个库,而require_relative
又是另一个库,而require
又是date
库。但更有趣的问题是,* 应该 * 使用
require
来运行date
库吗?答案是,* 是的 *,您应该这样做。依赖这样的require
链是非常脆弱的:如果在这条链中间的某个库决定改变它的内部结构,例如,使用不同的库来验证日期,或者自己实现日期验证,那么你的代码会无缘无故地中断。我通常遵循的规则是 * 每个脚本必须独立 ,即每个脚本必须
require
其所有依赖项。现在,在较大的应用程序中,这可能会变得很烦人,甚至可能会导致很长的启动延迟。一个很好的例子是框架或DSL,其中只是“期望”框架或DSL为您提供一组已经预加载的库。想象一下,您必须对每个
active_support
库、active_model
库、active_relation
库你在Ruby on Rails应用程序中使用的。这将是愚蠢的:如果您编写了Ruby on Rails模型,那么您 * 知道 *active_model
已经加载,您不需要再次加载它。所以,一个稍微宽松的规则是: 每个要成为
require
或由客户端执行的脚本必须独立 *。应用程序内部的脚本可能依赖于关于哪些库已经是required
的内部知识。