Extending your include knowledge of Ruby

extend and include are two confusing methods, but they go hand in hand like Lychee and Vodka (humm…). Hopefully I’ll try to clarify this as short as possible.

include(a_module) is called inside a class, and adds module methods as instance methods.

extend(a_module) adds all module methods to the instance it is called on.

Here’s a quick example:


  module InstanceMethods
    def an_instance_method
      "You called an_instance_method on #{self.class}"
    end
  end
  module ClassMethods
    def a_class_method
      "You called a_class_method_from_module on #{self}"
    end
  end

  class MyClass
    include InstanceMethods
    extend ClassMethods
  end

  my_class = MyClass.new
  puts my_class.an_instance_method # >> You called an_instance_method on MyClass
  puts MyClass.a_class_method      # >> You called a_class_method on MyClass

  obj = Object.new
  obj.extend InstanceMethods
  puts obj.an_instance_method      # >> You called an_instance_method on Object

As you can see, because extend is called inside the class (MyClass), and because Class is an object in Ruby, it adds module methods as class methods.

A common scenario for doing all this it to split large classes in several modules (and files), like is ActiveRecord::Base. To get rid of the extend ClassMethods you can take advantage of the included callback and rewrite to:


  module InstanceMethods
    def self.included(base)
      base.extend(ClassMethods)
    end
  end

  class MyClass
    include InstanceMethods
  end

Got any tips ? Share with us the way you use include and extend!

Chris point out another great article about include and exclude that is even more easier to understand for C#/Java programmer, thanks Chris!

About these ads

13 Comments

Filed under ruby, tutorial

13 responses to “Extending your include knowledge of Ruby

  1. Coding/girl

    Thans you very much for that exemple… i think that it’s going to help me in my future work. KEEP ON THE GOOD POSTS! We’re all fans of yours at my job

  2. Pingback: Ruby include and extend - chrisortman

  3. Wow! Thanks for the good words Coding girl, you made my day :)

  4. It seems that the ruby star shines well! :)

  5. thanks for the GREAT post! Very useful…

  6. I don’t get this at all!

    Are these extend and include things effectively built in commands to encourage monkeypatching? Terrifying!

    Why can’t you just refer to functions by their *full name* (including the module they are in) when calling them? It’s makes code much easier to read and maintain. You can find out where functions came from, and look them up.

    True, using explicity full names for things doesn’t work for methods. But if you really need that many methods, it sounds like your structure is wrong anyway – you should be abstracting some stuff out into separate classes.

    Call me old fashioned, but I think that all the methods of a class should be in one class definition file!

  7. @francis that _is_ another way to abstract stuff into seperate entities. Class inheritance and mixin are 2 seperate concept in OOP, you should read about mixin: http://en.wikipedia.org/wiki/Mixin

  8. Great post. I have enjoyed reading it.

  9. kannan

    Very good post. I want to clarify one more point that was confusing to me.

    There is nothing preventing the class MyClass to “extend InstanceMethods” or “include ClassMethods”.

    So you could say:

    class MyClass
    include ClassMethods
    extend InstanceMethods

    end

    MyClass.an_instance_method # You called an_instance_method
    MyClass.new.a_class_method # You called a_class_method

    The names are more of a convention to remind that the methods in the module InstanceMethods are to be “included” and the methods of module ClassMethods are to be “extended” than being enforced by the language.

  10. Dwelayday

    visit us!
    newsbox.cc
    newsbox.us
    nbstatus.wordpress.com
    NOW!

  11. Pingback: Ruby的extend與include « dev.poga.tw :Blog

  12. Taiwan’s designers from the East
    Hope that the friendship with you to establish friendly
    My interior design website
    仁川室內設計

  13. dingzhihu

    nice post about extend and include

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s