- understand the role the Modules play in Ruby
- use a module to create a mixin to make our code DRYer (Don’t Repeat Yourself)
Jot down your thoughts for the following questions. Be ready to share.
- What do you know about modules already? If little, what would you guess modules are all about based on the name?
- Football players and soccer players both have unique attributes. What behaviors might they share?
- What behaviors/abilities might be shared between an instructor and a student?
We’re going to learn about Modules, a simple tool that will do a few completely different things in Ruby. Today we are going to talk about using them as Mixins.
- Mixins allow us to share behavior between objects
- Ruby implements mixins with Modules
- Modules may look like classes, but they only hold methods
- Modules only store behavior
- Modules do not store state
- Modules cannot be instantiated. This means that you cannot type somethinglike
Let’s look at two separate classes to start exploring the idea of modules. Clone down this repo.
First, we’ll experiment with the
require "./status_update.rb" => true status = StatusUpdate.new("I'm learning about modules in Ruby #nbd") status.display status.add_comment("Oh cool!") status.add_comment("Just wait until you learn about inheritance.") status.add_comment("What is a module?") status.add_comment("I'm so proud of you! Love, mom.") status.display status.remove_comment(3) status.display
Now, let’s experiment with the
require "./photo.rb" => true photo = Photo.new("https://images.pexels.com/photos/2280545/pexels-photo-2280545.jpeg", "This is what I ate for breakfast #yum #hashtag") photo.display photo.add_comment("That looks delicious!") photo.add_comment("Ooooh, will you cook for me?") photo.add_comment("Brunch next Sunday?") photo.display photo.remove_comment(1) photo.display
Turn & Talk:
- What is similar/different between the two classes (StatusUpdate and Photo)?
- What design principle(s) are we breaking with these two classes? Explain.
module Commentable # what extracted code goes here? end
To get access to the methods defined in the module, you will include the module at the beginning of the class. Using include allows you to call the module methods on an instance of the class where it is included.
require "./commentable" class StatusUpdate include Commentable # ... other code end
require "./commentable" class Photo include Commentable # ... other code end
Get back into Pry and try out the interaction pattern below:
require "./status_update.rb" require "./photo.rb" status = StatusUpdate.new("I'm learning about modules in Ruby #nbd") status.display status.add_comment("Oh cool!") status.add_comment("Whoa...") status.display status.remove_comment(1) status.display photo = Photo.new("https://images.pexels.com/photos/2280545/pexels-photo-2280545.jpeg", "This is what I ate for breakfast #yum #hashtag") photo.display photo.add_comment("That looks delicious!") photo.add_comment("Pancakes!") photo.display photo.remove_comment(2) photo.display
Turn & Talk:
- What just happened there?
- What would be the benefit of a module?
- Where else might you be able to reuse
- Once a module is included in a class, any object created from that class can call the method in the module (we just treat it as if the
remove_commentmethods were part of our other classes, where you call the methods on an instance of an class.)
- Many classes can include the same module
- Each class can include many modules
Now it’s your turn.
Consider the following code:
class Camry def start puts "Engine on!" end def stop puts "Engine off!" end def drive puts "Back wheels go!" end end
class Jeep def start puts "Engine on!" end def stop puts "Engine off!" end def drive puts "All wheels go!" end end
- Create an
Enginemodule to extract the
stopmethods. (Yes, we know this isn’t following the “-able” naming conventions, but this is not a rule).
- Create an
Airconditionablemodule that is mixed into both classes. Instances of either class should be able to turn the AC on (
Chilly air coming your way!) or off (
Temp is fine in here.). It’s up to you what you want to name these methods.
- Now that stop and start are extracted to the module, add back in a start or stop method in one of your class. Have it return the string “WAIIIIIIIT”. What happens when you run this method? Why?
- In the exercise above, why didn’t we just tell you to have a ‘Vehicle’ module that could hold engine and AC? What might the benefit of those being separated be?
- What is a module? How is it different than a class?
- How do you allow a class to have access to module methods?