我的问题类似于“What is the difference between include and extend in Ruby?”。
Ruby 中的 require
和 include
有什么区别?如果我只想在我的类中使用模块中的方法,我应该require
还是include
?
Ruby 中的“include”和“require”有什么区别?回答: include 和 require 方法做的事情非常不同。 require 方法做了大多数其他编程语言中 include 所做的事情:运行另一个文件。它还会跟踪您过去需要的内容,并且不会两次需要相同的文件。要在没有此附加功能的情况下运行另一个文件,您可以使用 load 方法。 include 方法从另一个模块中获取所有方法,并将它们包含到当前模块中。这是一个语言级别的东西,而不是文件级别的东西,就像 require 一样。 include 方法是使用其他模块“扩展”类的主要方法(通常称为 mix-ins)。例如,如果你的类定义了方法“each”,你可以包含 mixin 模块 Enumerable 并且它可以作为一个集合。这可能会令人困惑,因为包含动词在其他语言中的使用方式非常不同。
因此,如果您只想使用一个模块,而不是扩展它或进行混合,那么您将需要使用 require
。
奇怪的是,Ruby 的 require
类似于 C 的 include
,而 Ruby 的 include
几乎与 C 的 include
完全不同。
如果您使用的是模块,这意味着您将所有方法都带入您的类。如果您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”
require
和 include
之间的区别是什么的问题。
来自元编程 Ruby 书,
require() 方法与 load() 非常相似,但它的目的不同。你使用 load() 来执行代码,你使用 require() 来导入库。
Ruby require 更像是其他语言(例如 C)中的“包含”。它告诉 Ruby 你想引入另一个文件的内容。其他语言中的类似机制是:在 C# 中使用
在 C# 中使用
在 Java 中导入
Ruby include 是一种用于 mixins 的面向对象的继承机制。
有一个很好的解释here:
[The] 简单的答案是 require 和 include 本质上是不相关的。 "require" 类似于 C 的 include,可能会导致新手混淆。 (一个显着的区别是,当请求完成时,所需文件中的本地变量会“蒸发”。)Ruby 包含与 C 包含完全不同。 include 语句将一个模块“混合”到一个类中。这是多重继承的一种有限形式。包含的模块字面上赋予包含它的事物“is-a”关系。
重点补充。
include
。命名空间、包和类类型对象都可以被视为特殊的环境,它们通常保存名称绑定。 (考虑 these differences 和 Kernel 的 $import!
。还要注意 Racket 的环境是在命名空间中实现的。)
从编程 Ruby 1.9
在继续之前,我们将对 include 语句提出几点意见。首先,它与文件无关。 C 程序员使用称为#include 的预处理器指令在编译期间将一个文件的内容插入到另一个文件中。 Ruby 的 include 语句只是对模块进行引用。如果该模块位于单独的文件中,则必须在使用 include 之前使用 require(或其不太常用的表亲 load)将该文件拖入。其次,Ruby 包含不会简单地将模块的实例方法复制到类中。相反,它从类中引用包含的模块。如果多个类包含该模块,它们都将指向同一事物。如果您更改模块中方法的定义,即使您的程序正在运行,包含该模块的所有类都将呈现新行为。
您是否尝试过require
一个模块?结果如何?试试看嘛:
MyModule = Module.new
require MyModule # see what happens
模块不是必需的,只有包括在内!
Module
更改为 Class
,任何运行上述代码的人都会发现他们收到相同的结果 (TypeError
)。
'Load' - 插入文件的内容。(每次调用文件时解析文件)
'Require' - 插入文件解析的内容。(文件解析一次并存储在内存中)
'Include' - 将模块包含到类中,并且可以使用模块内的方法作为类的实例方法
'Extend' - 将模块包含到类中,并且可以将模块内的方法用作类方法
包含 当您将一个模块包含到您的类中时,如下所示,就好像您将模块中定义的代码插入到您“包含”它的类中一样。它允许“混合”行为。它用于干燥您的代码以避免重复,例如,如果模块中有多个类需要相同的代码。
Load load 方法与 require 方法几乎一样,只是它不跟踪该库是否已加载。因此可以多次加载一个库,并且在使用加载方法时,您必须指定库文件名的“.rb”扩展名。
Require require 方法允许您加载一个库并防止它被多次加载。如果您在第一次之后尝试加载同一个库,require 方法将返回“false”。仅当您正在加载的库在单独的文件中定义时才需要使用 require 方法,通常是这种情况。
您可以更喜欢这个http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/
以下是require和include之间的一些基本区别:
要求:
Require 从文件系统读取文件,解析它,保存到内存并在给定位置运行它,这意味着如果您在脚本运行时更改任何内容,那么该更改将不会反映。我们需要文件名,而不是模块名。它通常用于库和扩展。
包括:
当您将模块包含到您的类中时,它的行为就像您将模块中定义的代码插入到您的类中一样。我们包括模块名称,而不是文件名。它通常用于干涸代码并删除代码中的重复项。
require(name)
它将返回布尔真/假
作为参数传递给 require 的名称,ruby 将尝试在您的加载路径中找到具有该名称的源文件。如果您在第一次之后尝试加载同一个库,require 方法将返回“false”。仅当您正在加载的库在单独的文件中定义时才需要使用 require 方法。因此它会跟踪该库是否已经加载。
include module_name
假设您有一些方法需要在两个不同的类中使用。然后,您不必在两个类中都编写它们。相反,您可以做的是在模块中定义它。然后将此模块包含在其他类中。 Ruby 提供它只是为了保证 DRY 原则。它用于干燥您的代码以避免重复
不定期副业成功案例分享
require
只是运行文件。时期。特别是,这意味着如果您将require
调用放在类声明中,文件中的代码将不会成为该类的一部分,如果您将require
调用放在方法定义,文件中的代码将不成为该方法的一部分,如果将require
调用放在模块声明中,文件中的代码将不 成为该模块的一部分,依此类推。它甚至没有成为require
调用所在文件的一部分。这里有很多关于 Stack Overflow 的问题是……include
只是继承。class C; include M end
使M
成为C
的超类,并使C
的(前)超类成为M
的超类。我不认为 C 的include
通过继承起作用,我认为它是简单的文本/词汇替换。