Developing gems in your Rails' lib/ directory

When you’re developing in Rails it can be handy to have some app-specific gems. I like them because they’re nicely isolated from the rest of the application and are grouped with their own test suites.

To create the gem go into your lib/ dir and run:

bundle gem my_gem

Then add it to your Gemfile:

gem 'my_gem', :path => 'lib/my_gem'

By default Rails will cache the gem. To prevent this add the following lines to your development.rb:

config.autoload_paths += %W(#{config.root}/lib/my_gem/lib)
ActiveSupport::Dependencies.explicitly_unloadable_constants << 'MyGem'

Adding your gem to the autoload path and adding its root module to the unloadable constants will prevent Rails from caching your gem’s classes between requests.

Now you won’t have to restart your app to see the changes made to your gem.

The Importance of Naming Things

There are only two hard things in Computer Science: cache invalidation and naming things
– Phil Karlton

The importance of properly naming classes, functions and variables is often overlooked. Yet doing it well can greatly enhance the readability of code.

I believe there are 2 main reasons why this is so hard:

  1. Most programmers tend to be “left-brainers”. Thus they tend to be more interested in solving logical puzzles. We’re excited to start solving a problem and tend to neglect thinking of proper names.

  2. When you’re having a hard time naming your functions, it could be an indicator that something is wrong in the design of your application.

I’m going to focus on the first reason here, because the second would be a bit too broad to cover in a single blog post.

You can find a lot of concrete tips online or in books. However, I want to give some more generic advice here, so you can get a better feel for why these tips work.

Let’s take an obvious and exaggerated example of bad naming:

# Bad
class Thing
  attr_reader :arr

  def initialize(arr)
    @arr = arr
  end

  def do_stuff(val)
    arr.keep_if do |a|
      a.include?(val)
    end
  end

end

t = Thing.new(['John', 'Jane', 'Carl'])
p t.do_stuff('o')


# Good
class NameArchive
  attr_reader :names

  def initialize(names)
    @names = names
  end

  def names_with_letter(letter)
    names.keep_if do |name|
      name.include? letter
    end
  end

end

archive = NameArchive.new(['John', 'Jane', 'Carl'])
p archive.names_with_letter('o')

The first example hides the meaning of the code. If complex code would use names like this, it would only be readable by the computer, or the person who wrote it (at least until he/she has to look back at it the next day/week/month).

The second example is easier to read and understand, because it reaches the goal of proper naming, which is to clearly express the intent of the code.

Luckily most programmers quickly get a basic level of proficiency in naming and quit bad habits like naming a variable array.

These were very basic examples though. Consistently coming up with good names becomes a bit trickier when working on large projects, so here are some tips:

  1. Look up the words!

    This counts for classes, functions and variables: If you’re having a hard time finding a good name, look it up in a dictionary. If you have a name, but it doesn’t feel quite right, then look up some related words on a site like Thesaurus.

    These days it’s very easy to just check a definition or a related word, so use it to your advantage. This is especially important if your native language isn’t English.

  2. Naming classes

    Most classes can be named pretty easily by using nouns from the use case (eg. “The User can create a Post).

    When this doesn’t work, like when you’re working on something more abstract, then its time to turn to google or the dictionary for inspiration.

    If you think your class name isn’t detailed enough, then don’t try to solve it by using generic terms like Manager or Data.

  3. Naming functions

    Make sure your function does one thing, and its name should describe that one thing in a clear way. Try to keep the function name concise, but don’t make it any shorter than it needs to be to stay descriptive.

    If you’ve spent some time finding a good name for a function and it still doesn’t feel right, then it may be sign that the function belongs in another, probably still-to-be-created, class.

  4. Naming variables

    Use clear variable names to indicate their content, but try to keep them short. A good rule of thumb is to keep them as short as possible without hiding their meaning in their context.

    For example, you don’t have to go and replace i with index in your for loops. Using i in loops has become convention and doesn’t require a longer name to be clear.

I hope this has made you a bit more aware of the importance of naming things. I think it’s a skill that’s often overlooked and takes a bit of persistence to get better at.

If you have written classes with some obscure variable names, then next time take a minute to think of, look up or even invent a good name before you start coding furiously. Unless, of course, you want to write unmaintainable code.

Refactoring with grep

The grep command is an awesome tool that people just don’t use enough. Learning to use it has greatly improved my productivity. It’s a powerful search tool that makes searching through code a lot easier without even needing an IDE.
grep can be used in a lot of situations, but here I’m just going to give a simple example of how I use it to help me while coding.

When looking up code I like to use it with the case-insensitive ( -i ) and recursive ( -r ) options. Suppose I was refactoring a JavaScript function called someFunction, then I would look up all occurrences of this string using grep. Just navigate to the root of the project and execute:

grep -ir "somefunction" .

This will do a case-insensitive search through all the files (in this directory or its subdirectories) and show all lines that contain the someFunction string. Now I can make sure to replace all these instances when I rename or adapt the function.

grep is very fast and you can make it even faster by limiting your search to certain directories:

grep -ir "somefunction" app/assets/javascripts
grep -ir "somefunction" public/javascripts

Combining this with globbing in zsh makes it even more powerful. Now you can search for files with a certain extension.
Like when you’re looking for a ruby function:

grep -i "some_other_function" **/*.rb

And if the result is not readable enough then you can add color ( --color ), line numbers ( -n or --line-number ) or some extra lines for context ( -C or --contex, e.g. -C5 or --context=5 ).

Design Patterns

In general, a design pattern is a reusable solution. Design patterns were first used in archictecture, when Christopher Alexander wrote about them in his book A Pattern Language: Towns, Buildings, Construction in 1977. Since then they have also been applied to computer science and they have been made popular by the Design Patterns book by the Gang of Four.

An example of a popular design pattern is Model-View-Controller. Even though these days it’s mostly regarded as an architectural pattern, it originated as a design pattern for GUI applications, where the components would have a model, view and controller.

For me, the two most important benefits of using design patterns are:

  1. They are a way to pass on knowledge. Designing an application the right way is hard. It’s especially hard doing it right from the beginning. To me, it’s quite common that solving a problem provides insights into how it could have been solved more efficiently. Design patterns can be those insights. In this sense they are design knowledge, passed on by more experienced developers.

  2. They ease communication about design. When we have names for the designs we are discussing, then talking about its tradeoffs and benefits becomes easier. Patterns allow us to use a higher level of abstraction when talking about the design of an application.

It’s not all good though… The concept of design patterns has been criticised by some smart people, whose opinions are certainly worth considering.

At the end of his essay Revenge of the Nerds, Paul Graham argues that the use of patterns in OO code is a sign that it doesn’t support powerful enough abstractions. He looks at it as an inefficient way (playing a human compiler) to solve a hard problem. Peter Norvig presents a very similar argument, claiming that 16 out of the 23 patterns in the Design Patterns book (focused on C++) can be simplified or eliminated in Lisp or Dylan.

Mark Dominus criticised the Design Patterns book for limiting the concept of patterns in computer science. He believes that design patterns as we currently know them aren’t a bad idea, but the original concept described in Christopher Alexander’s book is more powerful. The focus of the Gang-of-Four idea lies too much on reusing existing patterns instead of “helping you decide what should be designed” and “helping you make up patterns you think will lead to good designs”.

As proven by the criticisms above, the need for design patterns can be a form of a language smell. However when they become a language feature (or you make them via macros or metaprogramming), I believe you’re still applying them.

Patterns aren’t a silver bullet to solve all design issues, but they can be learned from. In the end it’s important to look at patterns as good programming solutions, which can either be reused or be a good inspiration to create your own.

Finally, if you want a good resource to learn patterns then I suggest the SourceMaking website. If you want know more of the criticisms on patterns then Ward Cunninghams wiki is a good place to start.