I'm a fan of naming things correctly.
I loathe Devise.
I just can't bring myself to read Enumerable source.
Why is that?!
TL;DR
Stop naming your modules in terms of what they do to the including class.
Instead, name them in terms of the behavior they provide.
# bad
module Enumerable
module Awarable
module DatabaseAuthenticatable
include Enumerable
# good
module Enumeration
module Awareness
module DatabaseAuthenticating
include Enumeration
The full discussion
For a long time I felt it's just how it is with me, you can't like every gem you use, right?
Then, one day, I encountered a module named Insurable
in our codebase and went: "That's just **** stupid! What the heck does it mean for a module to be insurable?! OK, maybe the module makes the including object insurable? This sounds awful lot like Devise with its Registerable
and Database Authenticatable
, yuck!".
So I feel an instinctive derision towards this sort of naming "convention" and per my own lesson, I went deeper. What is it about postfixing module names with "able" that makes my skin crawl? It may be that it defines the module in terms of what its inclusion does to the receiving class, where defining it in terms of itself would be preferable. Maybe the name gives away a code smell, a coupling, a reliance on functionality in the including object.
Is coupling a problem?
I'm fine with some coupling. Certainly, for Enumerable
the coupling is understandable, it relies on #each
having been defined, and that is OK. Modules should reflect this expectation with raising methods. Usually this looks like this:
module Enumerable
def each
raise("Expected to be overridden")
end
end
Give Ilija Eftimov's brilliant Testing Mixins in Isolation a read on how to spec this.
Could it be about the way it sounds?
It turns out that what gets me in about "*able" is that its awkward to talk about. Consider:
— This is the Enumerable module.
— Wut, the module is enumerable?
— No, no, the module makes the including class enumerable, see?
— So the module allows Enumerating?
— Yes.
— It provides Enumeration?
— Uh-huh..
Don't even get me started on participles like "awareness". Surely, it's not module Awarable
, but module Awareness (behavior/property)
.
I would recommend you name modules according to the behavior they encapsulate, try to express it directly, not through the including class. Do not fear sophisticated words, look at synonyms for ideas.
Top comments (4)
I actually like the
Somethingable
convention of naming modules, because for me it is natural to think of modules in terms of what they allow the including object to do.I do however dislike trying to name modules according to the
Somethingable
pattern, but I wonder if that's just a failure of my vocabulary.Awarable
is very clunky, though. Is the point that when included in an object, you can... make that object aware of something? Off the top of my head, I would have gone withAlertable
,Notifiable
or something. Something that, even if you don't like the naming convention, is actually recognisable as a word.I'd like to think that the ruby community is a very friendly one where we don't call other people's concepts or naming schemes "**** stupid". But that's just my humble opinion.
Besides that, it's not the module that's enumerable, instead, by including
Enumerable
the class becomes enumerable. The module, due to its nature, isn't capable of doing anything on its own, only inside a class it gives power to the class.Like I said, I haven't read the source, but taken at the face value of the name
include Enumeration
would absolutely be more understandable thaninclude Enumerable
.