Using the Right Words
Learn the importance of using the right names for variables, methods, classes, and so on.
We'll cover the following
Naming things is hard. Just like programmers are obsessed with formatting, they also care a lot about how to name the things they create.
Choosing good names for our variables, methods, and classes is important because this makes our code more expressive and easy to read. In fact, once we’ve learnt the basic concepts of Ruby, well-crafted code should read almost like prose. It’s not necessarily like your favorite novel, but maybe like a recipe or other instructional prose. Ruby is particularly great for writing expressive, readable code.
Here are some great and some rather bad example names.
Consider this code:
class Emaildef initialize(str, string2, headers_hash)# ...end# more methods ...endputs an_email = Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" })
Here, the author defines an Email
class, and it takes three arguments, two of which are probably supposed to be strings, and one is a hash containing some headers.
What’s the purpose of the first two arguments? All we know is that the author wants them to be strings. So, we might have to consult the documentation or look at examples using the class. Luckily, we can find an example at the bottom of the file and see that the first argument is the subject, while the second one is a date. It makes sense to rename these two arguments to subject
and date
to make it easier for others to understand their purpose.
When you tell your non-programmer friends that an email requires two strings and a hash of headers, they probably wouldn’t understand what you’re trying to say.
If you instead say that an email requires a subject, a date, and some headers, then they might roughly understand what you’re saying.
So, let’s rename them:
class Emaildef initialize(subject, date, headers)# ...endendputs email = Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" })
Using type for naming
Using an object’s type for a part of or the whole variable name is usually not a very good idea. For example, string
, array
, and hash
often are bad names, except in contexts where the object’s type is all that matters. One example of such a context is the def encrypt(string)
method definition in the Modules chapter.
Also notice that in the first example above, the str
argument name is an abbreviation. This is uncommon in Ruby. People used to use abbreviated variable names back when memory was extremely sparse and expensive because longer variable names consumed more memory. Nowadays, there’s no reason to make developers struggle with abbreviated names. Consider var
, var1
, var_2
bad names, and instead use names that reveal our intentions and their purpose.
Avoid the noise
Notice the local variable name an_email
in the first example above. The name email
in the second example is much better in most situations. The an_
prefix doesn’t add any information. It’s just noisy and adds clutter.
Remember: Great names reveal our intention while we write code. They reveal the purpose of our code and explain things to fellow developers.
Another example:
class Emaildef initialize(subject, date, headers)# ...endendemail = Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" })emailslist = [Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" }),Email.new("Keep on coding! :)", "2015-01-03", { :from => "Dajana" })]emailslist.each do |mail|puts mail.subjectend
Again, list
says something about the type. Why not just call it emails
? The plural already says that it’s some list.
Also, the mail
block argument deviates from the Email
class name and the emails
variable name. We might therefore ask if mail
is different from an email
in this code Why not avoid confusion like that in the first place and call it email
, simply the singular form of the name of the collection, emails
:
class Emaildef initialize(subject, date, headers)# ...end# more methods ...endemails = [Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" }),Email.new("Keep on coding! :)", "2015-01-03", { :from => "Dajana" })]emails.each do |email|puts email.subjectend