Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 自我包含–;在Ruby中包含模块中的类方法_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 自我包含–;在Ruby中包含模块中的类方法

Ruby on rails 自我包含–;在Ruby中包含模块中的类方法,ruby-on-rails,ruby,Ruby On Rails,Ruby,我读了这篇文章:–但仍然不知道什么时候你会使用self.included do。。。结束模块中的块 这篇文章说,当你包含模块时,块中的代码将被运行,但是如果模块的唯一目的是被包含,那又有什么意义呢?那代码不需要运行吗?为了让代码运行,那个块不需要存在,对吗 以下两者之间的区别是什么: module M def self.included(base) base.extend ClassMethods base.class_eval do scope :disable

我读了这篇文章:–但仍然不知道什么时候你会使用
self.included do。。。结束模块中的

这篇文章说,当你包含模块时,块中的代码将被运行,但是如果模块的唯一目的是被包含,那又有什么意义呢?那代码不需要运行吗?为了让代码运行,那个块不需要存在,对吗

以下两者之间的区别是什么:

module M
  def self.included(base)
    base.extend ClassMethods
    base.class_eval do
      scope :disabled, -> { where(disabled: true) }
    end
  end

  module ClassMethods
    ...
  end
end
vs

我试图修改上面的
模块
,以帮助您理解模块(关注点)如何有助于代码重用

self.included
是一个钩子,当类中包含模块时,它会自动运行

模块ClassMethods
中声明的任何方法都将成为包含此模块的类的类方法

模块ClassMethods
之外声明的任何方法都将成为包含此模块的类的实例方法

例如,假设有一个类产品,并且您已经将模块包含在其中

class Product < ActiveRecord::Base
  include M
  puts 'after including M'
end
它还提供了可重用性,将这个模块M包含在任何类中,该类可以访问模块中描述的所有方法

而您的第二个示例仅仅是基本模块的示例

module N
  def self.abc
    puts 'basic module'
  end
end
现在,只能使用此模块访问模块中定义的方法

N.abc#输出“基本模块”

class Product < ActiveRecord::Base
  include  N
end
类产品
Product.abc#引发异常,在类Product上找不到方法 Product.new.abc#引发异常,在类Product的对象上找不到方法

我希望这能帮助你更好地理解模块的概念。 如果您还有任何疑问,请告诉我。

这两个例子有什么不同? 第一个代码块将
ClassMethods
中的类方法添加到include类中,并对其调用
scope
方法。第二个函数既不做这两件事,也会导致一个
NoMethodError
,因为模块没有
scope
类方法<代码>自身。包含模块后,包含类上的某些类方法将不可用

有关模块包含在Ruby中如何工作的完整故事,请阅读我的回答:

如果一个模块的唯一目的是被包括在内,
self.include
有什么意义? 包含不是模块的唯一目的。它们还可用于其他用途,如名称空间或存储各种类方法,然后可在模块本身上调用这些类方法

为什么Ruby不自动包含类方法? 从理论上讲,Ruby可以自动将模块中定义的所有类方法添加到include类中,但实际上这是一个坏主意,因为将无法再选择是否要包含类方法-每次都会包含所有类方法,是否打算将其包括在内。考虑这个例子:

module M
  def self.class_method
    "foo"
  end

  def self.configure_module
    # add configuration for this module
  end
end

class C
  include M
end
这里,显然不应将
configure_module
方法添加到
C
,因为其目的是为模块对象设置配置。然而,如果我们有类方法的自动包含,您将无法阻止它被包含

但所有实例方法都已包含在内!那怎么样?


模块中的实例方法只有包含在类中时才真正有用,因为模块不能有实例,只有类才能有实例。因此,在一个模块中,每个实例方法都应该包含在工作的某个地方


模块上的“类”方法是不同的,因为它可以在模块本身上调用,所以无论是否也添加到include类中,它都可以很好地使用。这就是为什么你最好在这里选择。

听起来像是包含块将这些变量从另一个模块带到另一个模块。如果没有它,它不会工作吗?试着运行一个带有一些值的示例,看看它是否工作,请让我知道。你改变了密码?!!!为什么Product.abc即使包含了一个例外?是因为
#abc
仍然只在模块N的范围内,所以产品不能调用它吗?所以类方法必须在
包含的
基.extend
块内,而实例方法只能正常定义吗?是的
abc
仍然只能通过模块访问。当我们包含一个模块时,该模块中的类方法就不会包含在类中。这些方法仅适用于模块。@stackjlei-您甚至可以在self.included范围内定义实例方法。正如我告诉您的,self.include会在类中包含模块时立即调用,它可以用于为类定义
范围
,或者在包含模块时要执行某些操作<代码>模块类方法
也用于声明类方法。如果仍然存在疑问,请随时询问left@stackjlei我刚刚添加了一个答案,详细解释了幕后发生了什么,以及为什么我们首先要使用
self.include
块。你能用include解释一下原因吗“仅使其实例方法可用”?如果它们也使类方法可用,不是更容易吗?这样做有什么错吗?是因为包含只会在ancestorial查找中添加实例方法,但类方法仍然属于该模块吗?基本上是的,这是我在“类方法如何工作”中解释的“部分。我现在正在写一个更详细的解释。在“为什么Ruby不能自动执行此操作?”下添加了一些额外的解释。模块中的实例方法只有在包含到类中时才真正有用,因此我们希望包含所有这些方法。在第二个示例中(现在)
module N
  def self.abc
    puts 'basic module'
  end
end
class Product < ActiveRecord::Base
  include  N
end
module M
  def self.class_method
    "foo"
  end

  def self.configure_module
    # add configuration for this module
  end
end

class C
  include M
end