Welcome to Giant Robots Smashing Into Other Giant Robots — a weblog about development, business, design and technology — written by thoughtbot.
no need
Ruby’s modules give us opportunities to eliminate unnecessary classes from our designs.
In this example we have a citation, something that could be found in any academic paper, and 2 different ways of formatting it- MLA (Modern Language Association)
- CMS (Chicago Manual of Style)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
class Citation class << self def mla new MLAFormat.new end def cms new CMSFormat.new end end attr_reader :format def initialize(format) @format = format end def to_s format.format self end end class Format def format(citation) raise 'must be implemented with specific citation formatting' end end class MLAFormat def format(citation) 'MLA format' end end class CMSFormat def format(citation) 'CMS format' end end citation = Citation.new MLAFormat.new puts citation => 'MLA format' citation = Citation.new CMSFormat.new puts citation => 'CMS format' citation = Citation.mla puts citation => 'MLA format' citation = Citation.cms puts citation => 'CMS format' |
Here our Citation class delegates the formatting specifics to a Format object. And I also created some class methods on Citation to make creating a Citation with a specific format cleaner and simpler.
Now do the various Format classes need to be classes? I’d say no, they don’t require initialization and they have no state; they’re just behavior.
In Ruby we can use modules instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
class Citation class << self def mla citation = new class << citation include MLAFormat end citation end def cms citation = new class << citation include CMSFormat end citation end end def to_s format end end module MLAFormat def format 'MLA format' end end module CMSFormat def format 'CMS format' end end citation = Citation.new class << citation include MLAFormat end puts citation => 'MLA format' citation = Citation.new class << citation include CMSFormat end puts citation => 'CMS format' citation = Citation.mla puts citation => 'MLA format' citation = Citation.cms puts citation => 'CMS format' |
Here we mixin to a Citation object at runtime a specific format module. The Citation#to_s method is implemented in terms of #format, who’s implementation must be mixed in via a format module. So we’ve eliminated the abstract superclass, Format, changed 2 keywords from class to module and also eliminated the single citation argument from each Format module’s #format method.
Even though there’s not much difference between the 2 methods, I think using modules is more accurate because the classes just aren’t necessary.
About this entry
You're reading an entry on GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS, the company weblog of thoughtbot, inc.
- Author:
- Jared Carroll
- Published:
- September 10th 08:37 AM
- Updated:
- September 30th 09:57 AM
- Sections:
- Development
thoughtbot is hiring
We are hiring web developers and web designers in both Boston and New York, NY.
What are we up to?
We built Shoulda, an eclectic set of additions to Test::Unit; Paperclip to manage uploaded files without hassle; Jester, a REST/ActiveResource client library written in Javascript, and Squirrel, an enhancement for ActiveRecord's find syntax; — amongst some other projects.

Chad (President) and Jon (CTO) co-authored a technical book titled Pro Active Record: Databases with Ruby and Rails, which explores the ins and outs of the ActiveRecord ruby library. You can buy it today at Amazon.com.
About thoughtbot, inc.
We are a small web application development consulting business, with offices in Boston, MA and New York, NY. If you're looking to find a team for your next web development project or your new web application — get in touch.
9 comments
Jump to comment form