什么标准证明在Ruby中使用模块而不是类?

时间:2016-07-02 00:19:21

标签: ruby

我正在阅读我的红宝石书。看下面的代码,

module Destroy
  def destroy(anyObject)
    @anyObject = anyObject
    puts "I will destroy the object: #{anyObject}"
  end
end

class User
  include Destroy
  attr_accessor :name, :email
  def initialize(name,email)
    @name  = name
    @email = email
  end
end

my_info = User.new("Bob","Bob@example.com")
puts "So your name is: #{my_info.name} and you have email #{my_info.email}"

user = User.new("john","john@example.com")
user.destroy("blah")

我可以在课堂上创建另一种方法。我为什么要这样做?我为什么要使用模块?它不像将其嵌入其他类更容易,只是使用普通继承。

3 个答案:

答案 0 :(得分:3)

您可以将模块及其中的方法和常量视为更多提供实用程序功能和操作,您可以根据需要将这些功能和操作包括在其他对象中。例如,如果你想在对象FooBar中使用destroy函数,你可以这样做:

class Foo
  include Destroy
  # other code below
end

class Bar
  include Destroy
  # other code below
end

现在任何FooBar对象都可以访问destroy中的所有方法或常量。

模块定义了一个名称空间,一个沙箱,你的方法和常量可以在其中发挥,而不必担心被其他方法和常量踩到。 ruby docs对此有更深入的了解,并提供了一个很好的例子,可以在下面看到如何使用它:

module Debug
  def whoAmI?
    "#{self.type.name} (\##{self.id}): #{self.to_s}"
  end
end
class Phonograph
  include Debug
  # ...
end
class EightTrack
  include Debug
  # ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI?  »   "Phonograph (#537766170): West End Blues"
et.whoAmI?  »   "EightTrack (#537765860): Surrealistic Pillow"

在此示例中,包含Debug的每个类都可以访问方法whoAmI?以及Debug包含的其他方法和常量,而无需为每个类重新定义它。

答案 1 :(得分:2)

某些编程语言(如C ++,Perl和Python)允许一个类从多个其他类继承;这称为多重继承。 Ruby不支持多重继承。这意味着每个类只能从一个其他类继承。但是,有些情况下,类会通过获取多个其他类中定义的方法而受益。通过使用名为module的构造可以实现这一点。

模块有点类似于类,除了它不支持继承或实例化。它主要用作存储多种方法的容器。使用模块的一种方法是在类中使用include或extend语句。这样,该类就可以访问模块中定义的所有方法和对象。据说该模块混合在类中。因此,mixin只是一个类中包含的模块。单个模块可以混合在多个类中,单个类可以混合在多个模块中;因此,通过mixin功能消除了Ruby的单一继承模型所施加的任何限制。

模块也可用于命名空间。这在this post at the Practicing Ruby website中解释。

答案 2 :(得分:0)

您正在与该类在同一文件中编写模块,但不一定在该类中,但无论如何。

对我来说,使用模块有3个理由(更多细节here):

  1. 模块提供命名空间并防止名称冲突。
  2. 模块实现mixin工具。
  3. 当你有一个非常复杂和密集的课程时,你可以把它分成 模块并将它们包含在主类中。
  4. 你的例子很简单,在类本身编写方法确实更有意义,但试着想象一个复杂的场景。