Improve your Ruby syntax with Rubocop
As software developers, we are always trying to improve our projects: refactoring, updating gems, trying alternatives to make our applications faster and more reliable. But it seems that there is a topic about which it is very hard for us to come to an agreement: that's syntax.
Compare these classes:
class DummyClass end class SecondDummyClass end class AnotherDummyClass; end class AThirdDummyClass;end
Which one do you think is the right one, and why? All of them are right: all of them will run without any problems in our projects. The problem arises when one of the developers in your team uses the first one and you use the third one, but your client likes the fourth one and your Project Manager the second one: everyone will try to make the others use the syntax they like.
Rubocop is a code analyzer whose purpose is to force you to write code that follows the style guide dictated by the Ruby community.
Let's install Rubocop
gem install rubocop
You can run Rubocop directly in your app directory
cd your_app rubocop
But be careful: this will review ALL of your Ruby files in your application including gems. So you might want to be more selective about what to scan, and you can do it by sending an extra param to the
This will make Rubocop scan only the app directory. If we want to scan more files or directories, we can pass them as params
rubocop app spec config/application.rb
Let's do an example with this smelly code found in example\of_bad_code.rb_
class A_bad_named_class def ABadNamed_Method a = 2 if a a+=1 return true else return false end return false end end
Now we run
As soon as Rubocop finishes inspecting the files, we will get an output similar to this:
Inspecting 1 file W Offences: example.rb:1:1: C: Missing top-level class documentation comment. class A_bad_named_class ^^^^^ example.rb:1:7: C: Use CamelCase for classes and modules. class A_bad_named_class ^^^^^^^^^^^^^^^^^ example.rb:3:7: C: Use snake_case for methods. def ABadNamed_Method ^^^^^^^^^^^^^^^^ example.rb:6:7: W: Useless assignment to variable - a a+=1 ^ example.rb:6:8: C: Surrounding space missing for operator '+='. a+=1 ^^ example.rb:11:7: C: Redundant `return` detected. return false ^^^^^^ example.rb:12:5: W: end at 12, 4 is not aligned with def at 3, 2 end ^^^ 1 file inspected, 7 offences detected
The default output is a complete list of the problems found in our code.
The previous case showed 7 errors in a single file and the output is still easy to handle. But, what can we do when Rubocop reports hundred of errors?
Get in format with formatters
Rubocop provides us with a lot of formatters that display the output in different ways. We can specify the output format from the console by using the --format option:
The formatter I have found more useful is the offences formatter
rubocop example_of_bad_code.rb --format offences
Now the output will look like this:
1 EndAlignment 1 RedundantReturn 1 SpaceAroundOperators 1 UselessAssignment 1 MethodName 1 ClassAndModuleCamelCase 1 Documentation
As you may have guessed, this formatter groups the offences into categories and gives us a good overview of our project.
Cops and donuts
Now that we have an idea about what is wrong with our syntax, it's time to start taking a more detailed look to the cops. In Rubocop, a cop is the name of the specific 'error' presented in our code (i.e. EndAlignment cop tells us that an 'end' keyword is not properly aligned with its opening keyword)
Cops are divided into 3 types: Lint, Rails and Style
If we want to see a complete list of available cops, we can do it by running:
No offences allowed
By knowing the name of the cops, we can look up for a specific cop in our code by running:
rubocop --only EndAlignment
On the other hand, we might consider not to pay attention to certain cops. But, how can we exclude them from the analysis?
Setting a default behavior
The behavior of the analysis can be controlled via rubocop.yml, a file that can be placed in the root of your project or your home directory.
For example, to change the default line length in the LineLength cop from 79 to 60, we can add this to our Rubocop file:
LineLength: Max: 60
A complete list of cops and configuration options is found in the list of cops --show-cops
Fix all the things!
One of the coolest features in Rubocop is its ability to automatically fix certain kind of errors with the --auto-correct option
Before using this option, I really encourage you to stage the actual status of your project, just in case something goes wrong with the autocorrection:
Once that we have checked that the autocorrection didn't mess up our code, we can start fixing any remaining offences by hand.
Remember that these standards are outlined by the Ruby community and it is up to you to decide if each particular kind of offence is relevant to your project. You can find more information in the official repository. Thanks for reading!