gpt4 book ai didi

ruby - require 和 load wrt 到 "load"和 "execute"之间的区别

转载 作者:数据小太阳 更新时间:2023-10-29 07:14:08 26 4
gpt4 key购买 nike

以下是 Kernel 文档中的一些片段:

Kernel#load

Loads and executes the Ruby program in the file filename...

Kernel#require

Loads the given name...

我知道 require 之间存在差异和 load例如:

  • require将添加一个rb扩展 load不会
  • require会将 ruby​​ 文件路径存储在 $LOADED_FEATURES 中又名 $"同时load不会
  • require将搜索 $LOADED_FEATURESload 再次“加载”文件之前不会

我想知道“加载”这个词和“执行”这个词之间的区别。

文档使它们看起来像是两个不同的东西。对我来说,“加载”意味着“嘿,我现在知道这个文件了”,而“执行”意味着“嘿,我现在知道这个文件了,我也将运行所有命令”

但我认为那是不对的。

例如,给定以下结构:

$  tree
.
├── bar.rb
├── baz.rb
└── foo.rb

0 directories, 3 files

与 foo.rb:

$LOAD_PATH << __dir__
require 'bar'
load 'baz.rb'

酒吧.rb:

puts "Inside of bar..."

baz.rb:

puts "Inside of baz..."

当我运行 foo.rb我希望打印“Inside of baz...”而不是“Inside of bar...”,因为 loadrequire 时“加载并执行”只是“加载”。但实际上发生的是两者似乎都在“执行”:

$  ruby foo.rb
Inside of bar...
Inside of baz...

那么“加载”和“执行”ruby 文件有区别吗?

最佳答案

文件始终被执行。

在 Ruby 中,不存在加载文件而不执行文件这样的事情。在 Ruby 中,一切都是一条语句,必须被执行。甚至 classdef 也只是语句。

为了说明这一点,这里有一个愚蠢的例子

class Mystery < [Array, Object, String, Fixnum].sample
...
end

这将创建一个具有随机父类(super class)的类。只是为了说明 Ruby 没有声明,只有可执行语句。

所以不存在不执行 Ruby 文件这样的事情。 loadrequire 之间的区别正如您所描述的那样,后者会跟踪所有已加载的文件以避免重新加载它们。


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例子; end 是一条语句,内部调用define_method 方法。所以 def 只是方法调用的语法糖。

关于ruby - require 和 load wrt 到 "load"和 "execute"之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41411395/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com