【问题标题】:How many ways to include or inherit module inside a class有多少种方法可以在类中包含或继承模块
【发布时间】:2016-12-07 12:03:41
【问题描述】:

我正在尝试理解在类中包含或继承模块的概念。每当我阅读时,我都会获得在类中包含或继承模块的新方法。所以只想知道有多少种方法。以下是我分享的示例:

示例 1

module TimeExtensions
  refine Fixnum do
    def minutes; self * 60; end
  end
end

class MyApp
  using TimeExtensions

  def initialize
    p 2.minutes
  end
end

示例 2

VAL = 'Global'

module Foo
  VAL = 'Foo Local'

  class Bar
    def value1
      VAL
    end
  end
end

class Foo::Bar
  def value2
    VAL
  end
end

示例 3

module Foo
  def foo
    puts 'heyyyyoooo!'
  end
end

class Bar
  include Foo
end

【问题讨论】:

  • 这三个例子做了非常不同的事情。你可以问这三者之间有什么区别。另一方面,如果你只是想要相同的不同语法,你可以获得很多,但有什么意义呢?
  • 我正在学习如何在一个类中包含一个模块。每次我看到我得到不同的方式。所以我的问题是为什么有 3 种方法来做一件小事..
  • 这三件事彼此之间的关系为零。另外,这与 Rails 4 有什么关系?

标签: ruby ruby-on-rails-4 ruby-on-rails-5


【解决方案1】:

在这三个中,只有最后一个在类中包含一个模块。也就是说,它将模块中的方法添加到类中。


第一个叫做细化。如果不是精炼Fixnum,而是添加了#minutes 方法,Fixnum 将为使用它的每个人提供该方法,只要您的代码已加载。这可能会导致与同一方法的其他实现发生冲突(例如活动记录的#minutes),并导致晦涩难懂、难以调试的问题。相反,您可以细化 Fixnum 类,它只会在您使用 using 添加细化的范围内具有该方法。

它有一些问题,并且没有被广泛使用。但就这个问题而言,包含模块和使用细化之间的区别是:

  • include 会将方法添加到您执行包含的类中,而细化会使其他类在使用它们的上下文中表现不同
  • 包含是语义的(所有对象都将具有新的包含方法),而细化是词法的(关闭类后,如果再次重新打开,将看不到细化的方法)

第二个是在模块内确定类的范围。这不会在任何地方添加方法。正是由于搜索常量的方式,如果在当前类中找不到常量(在本例中为 VAL),则会在树的更上方进行搜索。其实没那么简单,如果你想了解更多细节,可以阅读here

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多