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)
Great article, thanks for sharing!
Great post!! Grats