以下是Kernel
文档中的一些代码段:
在文件filename ...
中加载并执行Ruby程序
加载给定名称......
我知道require
和load
之间存在差异,例如:
require
会在rb
分机上发布,而load
则不会require
会将ruby文件路径存储在$LOADED_FEATURES
又名$"
内,而load
则不会require
会在再次“加载”文件之前搜索$LOADED_FEATURES
,而load
将不会我想知道“加载”这个词与“执行”这个词之间的区别。
文档使它看起来像是两个不同的东西。对我来说,“加载”意味着“嘿,我现在知道这个文件”,而“执行”意味着“嘿,我现在知道这个文件了,我也要运行所有命令”
但我认为这不对。
例如,给定以下结构:
$ tree
.
├── bar.rb
├── baz.rb
└── foo.rb
0 directories, 3 files
与foo.rb:
$LOAD_PATH << __dir__
require 'bar'
load 'baz.rb'
bar.rb:
puts "Inside of bar..."
baz.rb:
puts "Inside of baz..."
当我运行foo.rb
时,我希望“在baz ...内部”打印而不是“在栏内......”因为load
“加载并执行”而{{1}只是“加载”。但实际发生的事情似乎都是“执行”:
require
“加载”和“执行”ruby文件之间有区别吗?
答案 0 :(得分:7)
始终执行文件。
在Ruby中没有加载文件而不执行文件。一切都是Ruby中的声明,必须执行。即使class
和def
也只是陈述。
这里说明这是一个愚蠢的例子
class Mystery < [Array, Object, String, Fixnum].sample
...
end
这将创建一个具有随机超类的类。只是为了说明Ruby没有声明,只有可执行语句。
所以没有不执行Ruby文件的事情。 load
和require
之间的区别如您所述,后者跟踪所有加载的文件以避免重新加载它们。
PS,另一个例子
ruby --dump insns -e 'def example; end'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
0000 trace 1 ( 1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject :example
0008 putiseq example
0010 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0012 leave
== disasm: <RubyVM::InstructionSequence:example@-e>=====================
0000 trace 8 ( 1)
0002 putnil
0003 trace 16 ( 1)
0005 leave
正如您所看到的,def example; end
是一个语句,并在内部调用define_method
方法。所以def
只是方法调用的语法糖。