Using the Right Words

Learn the importance of using the right names for variables, methods, classes, and so on.

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:

Press + to interact
class Email
def initialize(str, string2, headers_hash)
# ...
end
# more methods ...
end
puts 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:

Press + to interact
class Email
def initialize(subject, date, headers)
# ...
end
end
puts 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:

Press + to interact
class Email
def initialize(subject, date, headers)
# ...
end
end
email = 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.subject
end

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:

Press + to interact
class Email
def initialize(subject, date, headers)
# ...
end
# more methods ...
end
emails = [
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.subject
end