在Ruby中包含和扩展有什么区别?

刚开始讨论Ruby元编程。 mixin /模块总是会让我困惑。

  • 包括 :在指定的模块方法中混合使用目标类中的实例方法
  • 扩展 :将指定的模块方法混合为目标类中的类方法
  • 那么这个主要区别就在这个还是一个更大的龙潜伏? 例如

    module ReusableModule
      def module_method
        puts "Module Method: Hi there!"
      end
    end
    
    class ClassThatIncludes
      include ReusableModule
    end
    class ClassThatExtends
      extend ReusableModule
    end
    
    puts "Include"
    ClassThatIncludes.new.module_method       # "Module Method: Hi there!"
    puts "Extend"
    ClassThatExtends.module_method            # "Module Method: Hi there!"
    

    你所说的是正确的。 然而,除此之外还有更多。

    如果你有一个类Klazz和模块Mod ,包括Klazz ModKlazz访问Mod的方法的实例。 或者你可以用Mod扩展Klazz ,让Klazz类访问Mod的方法。 但是你也可以用o.extend Mod扩展一个任意的对象。 在这种情况下,即使所有其他具有与o相同的类的对象都没有,单个对象也会获得Mod的方法。


    扩展 - 将指定模块的方法和常量添加到目标的元类(即单例类),例如

  • 如果你调用Klazz.extend(Mod) ,现在Klazz有Mod的方法(类方法)
  • 如果你调用obj.extend(Mod) ,现在obj有Mod的方法(作为实例方法),但没有其他obj.class实例添加了这些方法。
  • extend是一种公共方法
  • include - 默认情况下,它将指定模块的方法作为目标模块/类中的实例方法进行混合。 例如

  • 如果你打电话给class Klazz; include Mod; end; class Klazz; include Mod; end; ,现在所有Klazz的实例都可以访问Mod的方法(作为实例方法)
  • include是一个私有方法,因为它打算从容器类/模块中调用。
  • 但是 ,模块通常会通过猴子修补included方法来覆盖include的行为。 这在传统的Rails代码中非常突出。 来自耶胡达卡茨的更多细节。

    有关include更多详细信息及其默认行为,假定您已运行以下代码

    class Klazz
      include Mod
    end
    
  • 如果Mod已经包含在Klazz或其祖先之一中,则include语句不起作用
  • 它还包括Mod在Klazz中的常量,只要它们不冲突
  • 它让Klazz访问Mod的模块变量,例如@@foo@@bar
  • 如果存在循环包含,则会引发参数错误
  • 附加模块作为调用者的直接祖先(即它将Mod添加到Klazz.ancestors中,但Mod不会添加到Klazz.superclass.superclass.superclass的链中。因此,在Klazz#foo中调用super将检查Mod#foo检查Klazz的真正超类的foo方法,详情请参阅RubySpec。)。
  • 当然,ruby核心文档总是最适合这些事情的地方。 RubySpec项目也是一个很好的资源,因为他们精确地记录了功能。

  • #include RubySpec ruby​​doc
  • #included RubySpec ruby​​doc
  • #extend RubySpec ruby​​doc
  • #extended RubySpec ruby​​doc
  • #extend_object RubySpec ruby​​doc
  • #append_features RubySpec ruby​​doc

  • 这是正确的。

    在幕后,include实际上是append_features的一个别名,它来自文档:

    Ruby的默认实现是将此模块的常量,方法和模块变量添加到aModule,如果该模块尚未添加到模块或其祖先之一。

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

    上一篇: What is the difference between include and extend in Ruby?

    下一篇: style pattern matching with type checking