Include vs. Extend…why not both?

If you don’t already know, there is a subtle difference between including and extending a module into one of your classes. include allows you to access instance methods while extend allows you to access class methods. See the example below for clarification:

module FooModule
  def foo
    puts 'foo'
  end
end

----------

class Bar
  include FooModule
end

Bar.new.foo => 'foo'
Bar.foo => NoMethodError: undefined method 'foo'

----------

class Bar
  extend FooModule
end

Bar.new.foo => NoMethodError: undefined method 'foo'
Bar.foo => 'foo'

So what if you want to create a module that will grant you access to both class and instance methods simultaneously? Luckily, using Rails’ ActiveSupport::Concern will help you separate your instance and class methods easily.

module FooModule
  extend ActiveSupport::Concern

  def foo
    puts 'foo'
  end

  module ClassMethods
    def baz
      puts 'baz'
    end
  end
end

----------

class Bar
  include FooModule
end

Bar.new.foo => 'foo'
Bar.foo => NoMethodError: undefined method 'foo'
Bar.new.baz => NoMethodError: undefined method 'foo'
Bar.baz => 'baz'

RubyMine – Creating live templates

Time is of the essence when you’re coding. Recently, I wrote about a line of code to get rid of a huge stack trace in rspec-rails. This will help you stay sane while you try to troubleshoot failing tests in your rails app.

config.backtrace_exclusion_patterns << /\.rvm\/gems/

However, you don’t want to have to keep typing this out every time you start a new rails app. If you use RubyMine, you’re in luck because you can just save this to a live template. Live templates act as auto-fill shortcuts in the same way that RubyMine predicts when you’re trying to type ApplicationController.


Creating a live template

If you want to create a live template, just highlight a line of text that you don’t ever want to have to type again, like the one above. Then go to the Tools Menu and select Save as Live Template. It will bring up a window where you can assign that code to an Abbreviation.

Live_Templates

Then just hit okay and go into any file in RubyMine. Start typing your abbreviation and you should see a window popup with a suggestion. In the example above, I just type in back and hit TAB to let RubyMine take care of the rest.

Disabling select cops in Rubocop

Rubocop is a wonderfully pesky code analyzer. It analyzes written code and raises warnings for any lines that don’t follow best practices for programming in Ruby. You can run it as a standalone, or if you’re familiar with Guard, you can automate it and get real-time suggestions as you code. While it’s an amazing tool to make sure that you’ve crossed your T’s and dotted the I’s, it’s still just a tool. Occasionally, it will point out certain style errors that you just don’t care about or are forgivable given other circumstances.


Leave me alone Rubocop!

The other day, I was writing a small program to print out the lyrics of the song ’99 Bottles of Beer.’ I thought I had written a pretty slick program until I checked my Rubocop output.

11 offenses?! What?! How?!

Okay, half of them turned out to be minor, like forgetting a closing parentheses here and there. But Rubocop wouldn’t stop bugging me about 6 lines of code that were “too long.”

methods_and_recursion/bottles_of_beer.rb:11:81: C: Line is too long. [82/80]
  first_part = "#{number} bottles of beer on the wall, #{number} bottles of beer."

You see, best practices dictate that code shouldn’t run over 80 characters long so that your program is easily readable. Think about how books are published. Would you like to read a novel where each paragraph was condensed into just 2 or 3 really long lines and the book was 4 feet wide? Didn’t think so…

But what if your lines of code are just SLIGHTLY over the limit. We’re talking about 2 measly characters! If I caved to Rubocop’s bullying, my code might end up looking manky, like this:

first_part = "#{number} bottles of beer on the wall, " +
             "#{number} bottles of beer."

In this case, I think being just slightly over the column width limit is okay. The code is still totally readable and is MUCH better than trying to break it up into two lines.


Disabling Rubocop within source code

Rubocop is made up of a bunch of ‘cops’ that patrol your code. One cop might make sure there aren’t any extra lines of whitespace and another might check to see all parentheses are closed off somewhere. The team that developed Rubocop predicted that sometimes you might want to disable some cops in your code.

It’s fairly straightforward to do, but I wanted to add some words of caution. Disabling a cop will help prevent Rubocop from incessantly reminding you that you suck at coding, but that’s a double-edged sword. If you’re prone to forgetting to close parentheses, maybe you need Rubocop to remind you of your bad habit until you fix it.

The nice thing about disabling Rubocop within code is that you can disable and re-enable cops within a program. So, if you wanted to ignore warnings in a block of code that pertained to ‘LineLength’ and ‘StringLiterals’, you could wrap code with comments to disable/enable cops whenever you want. Be sure to add some comments to remind yourself why you disabled the cop in the first place.

# The following lines have output that is too long, so I
# disabled the LineLength cop for this one section of code
# rubocop:disable Metrics/LineLength, Style/StringLiterals
[...]
# rubocop:enable Metrics/LineLength, Style/StringLiterals

Check out the RubyDoc for Rubocop for an overwhelming list of all cops.


How NOT to do it!

I’ll just add one more thing to this discussion. There might be some files, or even directories, that you just want Rubocop to ignore. In that case, you should create a `.rubocop.yml` file in your project directory. You can modify it to have all cops completely ignore certain files/directories. In addition, you can disable certain cops from raising warnings even in the files that are being scanned.

AllCops:
  Exclude:
    - 'vendor/**/*'
    - 'spec/fixtures/**/*'

Style/Encoding:
  Enabled: false

Just remember, Rubocop is there to help your code look better. Your colleagues will appreciate it and it will probably make you more attentive to detail in the long run. If you disable a lot of cops in `.rubocop.yml`, your code might end up looking a little bit sloppy. So…wield this power responsibly.