DEV Community

Cover image for Ruby Modules
Laura Berge
Laura Berge

Posted on

Ruby Modules

When we write classes in Ruby, we may find that we end up using a lot of code just for methods. In Ruby, we can use modules to abstract out any methods our class needs access to. (If you're unfamiliar with Ruby classes, you can check out a blog I wrote on classes and instances in Ruby here). We declare modules in a similar way to classes. For example, we're going to use a class of Dog that is going to need access to many methods.

class Dog
    attr_accessor :name

    def initialize(name)
        @name = name
    end
end

Instance Methods in Modules

Now that we have our class, we're going to create a module to store methods our individual dogs may need access to.

module DogInstanceMethods
    def speak
       puts "Woof!"
    end

    def growl
        puts "Grrrr..."
    end

    def sit
        puts "*sits*"
    end

    def walk?(energy)
        if energy
            true
        else
            false
        end
    end
end

In order to include DogInstanceMethods in our Dog class, we need to use the 'include' keyword.

# make sure to include the filename with the module at the top such as:
# require_relative DogInstanceMethods.rb

class Dog
    include DogInstanceMethods
end

jitta = Dog.new("Jitta")
jitta.speak #=> "Woof!"

Class Methods in Modules

Now this works great for instance methods, but what about class-level methods? When declared inside a class, we use self to tell our program we're operating on Dog as a class. However, self in the module is the module DogInstanceMethods itself. So in order to include class methods, we use the same format as above except we use extend instead of include.

module DogClassMethods
    def species
        puts "Canis Lupus"
    end

    def fun_fact
        puts "Dogs have unique nose prints like humans have fingerprints."
    end
end


class Dog
    extend DogClassMethods
end

Dog.fun_fact #=> "Dogs have unique nose prints like humans have fingerprints."

Nesting Modules

Let's put our class and instance methods under the same roof in order to keep the code organized. We can nest them within a larger module called DogMethods and refer to them using 'OuterModule::InnerModule'.

module DogMethods
    module InstanceMethods
        def speak
            puts "Woof!"
        end
    end

    module ClassMethods
        def species
            puts "Canis Lupus"
        end
    end
end

class Dog
    include DogMethods::InstanceMethods
    extend DogMethods::ClassMethods

    attr_accessor :name

    def initialize(name)
        @name = name
    end
end

jitta = Dog.new("Jitta")
jitta.speak #=> "Woof!"
Dog.species #=> "Canis Lupus"

Questions

Feel free to leave any questions or comments about modules in Ruby. Happy coding!

Top comments (2)

Collapse
 
cescquintero profile image
Francisco Quintero 🇨🇴

Great article, thanks for sharing!

Collapse
 
thadeu profile image
Thadeu Esteves Jr

Great post!! Grats