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}"
  module ClassMethods
    def a_class_method
      "You called a_class_method_from_module on #{self}"

  class MyClass
    include InstanceMethods
    extend ClassMethods

  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)

  class MyClass
    include InstanceMethods

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!


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


    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!

  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 )

Connecting to %s