rubymixinsprependruby-2.0

What is the difference between 'include' and 'prepend' in Ruby?


From the Module

Module#append_features(mod) → mod

When this module is included in another, Ruby calls append_features in this module, passing it the receiving module in mod. Ruby’s default implementation is to add the constants, methods, and module variables of this module to mod if this module has not already been added to mod or one of its ancestors.

Module#prepend_features(mod) → mod

When this module is prepended in another, Ruby calls prepend_features in this module, passing it the receiving module in mod. Ruby’s default implementation is to overlay the constants, methods, and module variables of this module to mod if this module has not already been added to mod or one of its ancestors.

Can anyone help me to understand the below questions:


Solution

  • As specified in the text you quoted:

    the constants, methods, and module variables

    Both add methods of the mixed-in module to the passed module (class). The difference is in the lookup order of these methods, in case that the target class already has them defined:

    include behaves as if the target class inherited mixed-in module:

    module FooBar
      def say
        puts "2 - Module"
      end
    end
    
    class Foo
      include FooBar
    
      def say
        puts "1 - Implementing Class"
        super
      end
    end
    
    Foo.new.say # =>
                # 1 - Implementing Class
                # 2 - Module
    

    prepend makes the methods from the mixed in module "stronger" and executes them first:

    module FooBar
      def say
        puts "2 - Module"
        super
      end
    end
    
    class Foo
      prepend FooBar
    
      def say
        puts "1 - Implementing Class"
      end
    end
    
    Foo.new.say # =>
                # 2 - Module
                # 1 - Implementing Class
    

    The example kindly ripped off from here: http://blog.crowdint.com/2012/11/05/3-killer-features-that-are-coming-on-ruby-2-0.html

    Use prepend when you want to keep methods of the target module (class) at the end of the method lookup chain.

    Some real-world examples can be found by searching SO for ruby, module and prepend:

    (Note: I am mentioning only methods, as they are easiest to picture when it comes to inheritance and mixing-in, but the same applies to other features.)