Ruby is a great programming language. As programmers, it allows us to do almost everything in our minds, and even more than that. But with power, comes great responsibility, and the responsibility to use Ruby’s features wisely is on the developers shoulders.
The few last lines might sound a little vague, so let’s take an example of a great Ruby feature that (IMHO) might cause a lot of harm if not used with care.
Attribute readers in ruby are a common used feature in the language. Let’s take a look at an example:
So we have
attr_writer definitions followed by their ruby equivalent. They basically let you read and set the
@balance instance variable of the class
This is great, it allows us to easily define setters and getters for our class’s members, so they can be used outside of the
BankAccount class itself.
The problem starts when programmers use those getters and setters internally in the class in such a way that might confuse others who might not know the class that well. The following example shows a use of attr readers and writers and the same function with instance variables:
When I read the first function, these are the questions which might come to my mind:
- In line #2, is
old_balancea member of the class
BankAccountor is it a local variable in the
- That makes me also wonder if
old_balance=is a method defined within the
BankAccountclass or is it a simple variable assignment expression.
balancea member of the class
BankAccountor is it a method call in the class?
- The same goes for
balance=in line #3. Does it set an instance variable named
@balance? Is it a simple variable assignemnt?!
OK, you got the idea😉
If we follow the convention of using instance variables inside the class they belong to instead of the reader and writers method, we get the second function which is a lot clearer:
- It is obvious that
old_balanceis a local variable of the
- It also clears the fact that line #10 is a simple variable assignment statement and not a writer method of the
- You know for sure
@balanceis an instance variable and that
@balance =is an assignment into this instance variable
- Thanks good for inventing Syntax Highlighting! Now all our usage of instance variables is highlighted in a different color than the rest of the variables – the locale ones.
But I Have To!
If you need to use attribute readers and writers from within the class, please do yourself and your co-workers a favor and use explicit method calls. Explicit method calls use the
self. prefix to indicate we’re calling a method and not assigning a local variable.
This is how the
balance_boost method would look like using explicit method calls:
This has the same effect as using instance variables: There is definite difference between local variables and instance methods which alter instance variables. We also get the syntax highlighting to make it even more obvious.
Whenever you are using attribute readers and writers from within the class without making an explicit method call (using self.) you confuse your teammates and make your code less obvious.
Make yourself clear, use the instance variables themselves or explicitly call the reader/writer methods.
Remember, you don’t want others to make an effort to understand your code, you want them to understand it from first sight.