为什么我们要在Ruby的类中放一个模块?

在Ruby中,为了命名空间的缘故,我发现将模块放在模块内可能很有用。 我也看到可以将模块放在类中。 但我不明白你为什么这么做。

模块通常被混合到类中,对吗? 那么,在类中定义模块的目的是什么?


我们可以在编写像这样的类猿代码时使用它:

class DrugDealer
  module Drug
    def happy?; true; end
  end

  def approach(victim)
    victim.extend Drug
  end
end

o = Object.new
DrugDealer.new.approach(o)
o.happy? # => true

在现实世界中更实际的另一个例子是混合只应用于子类。

当某个事物的某些方面适用于某些子类并且其他方面适用于其他子类时,这非常有用,但这些方面没有足够的顺序来为清晰的类层次结构(树)开路。 想想多重继承! 一个简单的例子:

class Person
  def handshake
    :sloppy
  end

  def mind_contents
    :spam
  end

  module Proper
    def handshake
      :firm
    end
  end

  module Clever
    def mind_contents
      :theories
    end
  end
end

class Professor < Person
  include Proper
  include Clever

  # ...
end

等等。 一种很好的,当用于明智的。 即使是超级调用和构造函数(我没有在这里定义),按照我希望的方式流过所有混合类和类。


class Image
    module Colors
        Red = ...
        Blue = ...
    end
    include Colors
end

include Image::Colors

Image.new.set_pixel x, y, Red 

我已经在具有复杂命名空间的大型Rails应用中遇到了一个用例。 一个简单的例子:

# app/models/invoice/dependents/item.rb
class Invoice
  module Dependents
    class Item
      # Define invoice item
    end
  end
end

这里的Invoice是它自己的一个类,但是它的依赖项也是一个很好的名字空间。 我们不能说module Invoice因为该常量已经被定义为一个类,但是我们仍然可以使用它作为一个名称空间。

巨人警告

如果您使用类作为命名空间,并且您正在使用Rails,请确保您不会意外地在其他地方声明该类 。 自动加载会毁了你的一天。 例如:

# app/helpers/invoice/dependents/items_helper.rb
class Invoice       # This line will cause you grief
  module Dependents
    module ItemsHelper
      # view helper methods
    end
  end
end

在此文件中声明class Invoice的事实会创建加载顺序依赖性; 如果此文件的class Invoice行在您想要的类定义之前执行,则您的预期类定义可能无法正常工作 。 在这个例子中,如果Invoice已经声明没有父类,我就不能声明这个Invoice sublcasses ActiveRecord::Base

可以在另一个文件的顶部需要你的“真实”类定义文件,但至少在Rails自动加载的情况下,如果你这样做,你将不会有更多的争论:

# app/helpers/invoice/dependents/items_helper.rb
module Invoice:Dependents::ItemsHelper  
  # view helper methods
end

使用这种语法,Rails将看到Invoice常量并使用自动加载来查找它,并在您的模型文件中找到它并按照您的意图进行定义。

链接地址: http://www.djcxy.com/p/44841.html

上一篇: Why would we put a module inside a class in Ruby?

下一篇: Ruby function to remove all white spaces?