ChatGPT解决这个技术问题 Extra ChatGPT

Ruby 中的 include 和 require 有什么区别?

我的问题类似于“What is the difference between include and extend in Ruby?”。

Ruby 中的 requireinclude 有什么区别?如果我只想在我的类中使用模块中的方法,我应该require还是include

值得一提的是,这里是 requireinclude 以及相关的 Module#append_features 社区文档的链接。

s
stkent

Ruby 中的“include”和“require”有什么区别?回答: include 和 require 方法做的事情非常不同。 require 方法做了大多数其他编程语言中 include 所做的事情:运行另一个文件。它还会跟踪您过去需要的内容,并且不会两次需要相同的文件。要在没有此附加功能的情况下运行另一个文件,您可以使用 load 方法。 include 方法从另一个模块中获取所有方法,并将它们包含到当前模块中。这是一个语言级别的东西,而不是文件级别的东西,就像 require 一样。 include 方法是使用其他模块“扩展”类的主要方法(通常称为 mix-ins)。例如,如果你的类定义了方法“each”,你可以包含 mixin 模块 Enumerable 并且它可以作为一个集合。这可能会令人困惑,因为包含动词在其他语言中的使用方式非常不同。

Source

因此,如果您只想使用一个模块,而不是扩展它或进行混合,那么您将需要使用 require

奇怪的是,Ruby 的 require 类似于 C 的 include,而 Ruby 的 include 几乎与 C 的 include 完全不同。


事实上,C 的 include 并不像 require 那样加载文件,而是用文件的内容替换 #include 行。包含的文件不必是“标题”,#include 不必位于文件的开头,而是可以在任何地方,例如在类中甚至方法定义中。这意味着您可以通过在文件中编写一些方法并将其包含在类的代码中来在 C++ 中进行 mixin,这正是您在 ruby 中所做的。所以它们并没有那么远,尽管这在 C 语言中确实不是一种常见的做法。
这个答案可以通过包含示例来受益。
mb14 的评论暗示了这一点,但它需要明确说明:与答案所说的相反,require 不会“运行”文件,而是将其加载,就好像它是包含文件的一部分一样。这可能看起来像是语义上的吹毛求疵,但实际上这是一个相当重要的区别。
@LonnyEachus:这是错误的。 require 只是运行文件。时期。特别是,这意味着如果您将 require 调用放在类声明中,文件中的代码将不会成为该类的一部分,如果您将 require 调用放在方法定义,文件中的代码将成为该方法的一部分,如果将 require 调用放在模块声明中,文件中的代码将 成为该模块的一部分,依此类推。它甚至没有成为 require 调用所在文件的一部分。这里有很多关于 Stack Overflow 的问题是……
@GregSchmit:Ruby 中的 include 只是继承。 class C; include M end 使 M 成为 C 的超类,并使 C 的(前)超类成为 M 的超类。我不认为 C 的 include 通过继承起作用,我认为它是简单的文本/词汇替换。
A
Andrei

如果您使用的是模块,这意味着您将所有方法都带入您的类。如果您extend一个带有模块的类,这意味着您将模块的方法“引入”为 class 方法。如果您include 一个带有模块的类,这意味着您将模块的方法“引入”为 instance 方法。

前任:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => B:Class 的未定义方法“say”

B.new.say =>这是模块 A

C.say =>这是模块 A

C.new.say => C:Class 的未定义方法“say”


我认为这不能回答问题,但这是我要找的=)
这实际上并没有回答 requireinclude 之间的区别是什么的问题。
J
Jonathan Fretheim

来自元编程 Ruby 书,

require() 方法与 load() 非常相似,但它的目的不同。你使用 load() 来执行代码,你使用 require() 来导入库。


赞成在您的答案中不与另一种语言进行比较:)
否决在问题的上下文中不提供答案:“如果我只想使用班级中模块中的方法?”
I
Iulian Onofrei

Ruby require 更像是其他语言(例如 C)中的“包含”。它告诉 Ruby 你想引入另一个文件的内容。其他语言中的类似机制是:在 C# 中使用 指令。在 Java 中导入

在 C# 中使用 指令。

在 Java 中导入

Ruby include 是一种用于 mixins 的面向对象的继承机制。

有一个很好的解释here

[The] 简单的答案是 require 和 include 本质上是不相关的。 "require" 类似于 C 的 include,可能会导致新手混淆。 (一个显着的区别是,当请求完成时,所需文件中的本地变量会“蒸发”。)Ruby 包含与 C 包含完全不同。 include 语句将一个模块“混合”到一个类中。这是多重继承的一种有限形式。包含的模块字面上赋予包含它的事物“is-a”关系。

重点补充。


模块导入不像文件包含那样,因为它与程序的外部源表示无关。它更像这里的 include。命名空间、包和类类型对象都可以被视为特殊的环境,它们通常保存名称绑定。 (考虑 these differences 和 Kernel 的 $import!。还要注意 Racket 的环境是在命名空间中实现的。)
c
cizixs

从编程 Ruby 1.9

在继续之前,我们将对 include 语句提出几点意见。首先,它与文件无关。 C 程序员使用称为#include 的预处理器指令在编译期间将一个文件的内容插入到另一个文件中。 Ruby 的 include 语句只是对模块进行引用。如果该模块位于单独的文件中,则必须在使用 include 之前使用 require(或其不太常用的表亲 load)将该文件拖入。其次,Ruby 包含不会简单地将模块的实例方法复制到类中。相反,它从类中引用包含的模块。如果多个类包含该模块,它们都将指向同一事物。如果您更改模块中方法的定义,即使您的程序正在运行,包含该模块的所有类都将呈现新行为。


B
Boris Stitnicky

您是否尝试过require一个模块?结果如何?试试看嘛:

MyModule = Module.new
require MyModule # see what happens

模块不是必需的,只有包括在内!


这里的断言是不正确的。可能需要模块。如果将单词 Module 更改为 Class,任何运行上述代码的人都会发现他们收到相同的结果 (TypeError)。
V
Vaishali Venkatesan

'Load' - 插入文件的内容。(每次调用文件时解析文件)

'Require' - 插入文件解析的内容。(文件解析一次并存储在内存中)

'Include' - 将模块包含到类中,并且可以使用模块内的方法作为类的实例方法

'Extend' - 将模块包含到类中,并且可以将模块内的方法用作类方法


S
Sanket

包含 当您将一个模块包含到您的类中时,如下所示,就好像您将模块中定义的代码插入到您“包含”它的类中一样。它允许“混合”行为。它用于干燥您的代码以避免重复,例如,如果模块中有多个类需要相同的代码。

Load load 方法与 require 方法几乎一样,只是它不跟踪该库是否已加载。因此可以多次加载一个库,并且在使用加载方法时,您必须指定库文件名的“.rb”扩展名。

Require require 方法允许您加载一个库并防止它被多次加载。如果您在第一次之后尝试加载同一个库,require 方法将返回“false”。仅当您正在加载的库在单独的文件中定义时才需要使用 require 方法,通常是这种情况。

您可以更喜欢这个http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/


A
Awais Shafqat

以下是require和include之间的一些基本区别:

要求:

Require 从文件系统读取文件,解析它,保存到内存并在给定位置运行它,这意味着如果您在脚本运行时更改任何内容,那么该更改将不会反映。我们需要文件名,而不是模块名。它通常用于库和扩展。

包括:

当您将模块包含到您的类中时,它的行为就像您将模块中定义的代码插入到您的类中一样。我们包括模块名称,而不是文件名。它通常用于干涸代码并删除代码中的重复项。


C
Caleb Kleveter
require(name)

它将返回布尔真/假

作为参数传递给 require 的名称,ruby 将尝试在您的加载路径中找到具有该名称的源文件。如果您在第一次之后尝试加载同一个库,require 方法将返回“false”。仅当您正在加载的库在单独的文件中定义时才需要使用 require 方法。因此它会跟踪该库是否已经加载。

include module_name

假设您有一些方法需要在两个不同的类中使用。然后,您不必在两个类中都编写它们。相反,您可以做的是在模块中定义它。然后将此模块包含在其他类中。 Ruby 提供它只是为了保证 DRY 原则。它用于干燥您的代码以避免重复