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."
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"
Feel free to leave any questions or comments about modules in Ruby. Happy coding!