I’ve never liked the “[verb]-able” naming convention for mixins in Ruby. If I have, say, a RockClimber class and I am mixing in a “climb” method, this convention means the mixin is named “climbable”. A rock climber isn’t climbable, though; a rock climber isn’t an object that can be climbed, it is an object that is capable of climbing. The verb-able naming convention seems to imply that mixins are about what can be done to an object (“climbable” — “this object can be climbed”), rather than what an object is capable of doing (“this object can climb”).
A while ago, I decided to see if I could come up with a convention I liked better. In Scala, traits are an analog to mixins. The naming convention for adding a climb method to a class in Scala with a trait would be to name the trait “Climber” – the noun that means “something that can climb”. I imagine this is because Scala traits are much like interfaces in other languages, which are often named this way, and I don’t particularly like this convention for mixins either. A mixin, unlike a trait, isn’t a type, and shouldn’t be named like it is.
One of the suggestions I found while searching naming conventions for mixins was the can-verb convention (e.g. CanClimb
). I think this is an improvement, because it correctly classifies the behavior that a mixin would enable, but in considering this possibility, I hit upon the other thing I don’t like about mixins in Ruby: the “include MixinName” syntax doesn’t read like English.
In a language community so (rightly) obsessed with making code as English-readable as possible, to the point where you might test an object’s ability to climb with something like:
rock_climber.should be_able_to_climb
A line like this:
include CanClimb
seems remarkably clunky.
How do we make it less clunky? Well, we could alias the include method. For example, we could call it “can”, and just make mixins straight verbs like “Climb”. What I eventually settled on, at least for small personal projects was similar to this. “can Climb” as a way to include a mixin is very readable, but (and this is getting pretty nitpicky) I would prefer not to name mixins in exactly the same way I name methods.
What I settled on in the end was this idea:
class Module
def tricks(*modules)
modules.each(&method(:include))
end
end
class RockClimber
tricks Climbing
end
The mixin naming convention is a gerund, that is, a verb form that can function as a noun (e.g. climbing, running, jumping). This doesn’t conflict with any naming conventions for other code constructs that I know of, and it has the advantage of making sense in a list form, so that you don’t need multiple include lines for different mixins. The inclusion of mixins answers the question “What tricks can this class do?” and the fact that they are called “tricks” provides a logical name for the folder to put them in: the “tricks” folder.
It’s working well for me so far.