Ruby Command Line Application

Ruby is a powerful dynamically typed, object oriented programming language created by Yukihiro “Matz” Matsumoto in 1995. Its strength is in its almost English sentence reading syntax as well as its flexible and open object oriented system.

Further Material

Topics, Tools and Terms

Ruby packages are called gems, and the tool to install new packages, called (gem), comes with the Ruby language distribution itself. gem lets us run install commands to add packages to our system, for example gem install rails will install Rails on our system.

Dependency Management

Having to install dependencies by hand quickly becomes tedious and time consuming. Luckily we have a tool called Bundler to help with that; Bundler needs to be installed as a gem: gem install bundler. This will install Bundler globally with the other gems on our system and provide the executable bundle for us which we’re going to use later.

Now we have a way to bundle and manage our dependencies in a file called a Gemfile. The content of that file is a list of gems we need for a given project. An example Gemfile looks like this:

source "https://rubygems.org"
gem "rails", "5.0.2"

The first line tells Bundler where to look for all gems. Rubygems.org is a central place where Ruby gems are available. The second line adds Rails as a dependency (with version 5.0.2). This is helpful to make sure every developer has the same versions installed on their systems. It is also helpful when we deploy our Ruby applications to a server for the same reason.

To have bundler installing everything needed for us we run bundle install. This will download all dependencies specified in the Gemfile.

Version Managers

Once you start working on more than one Ruby project a version manager will prove very beneficial.

Without a version manager we’d need to always install the currently needed version of Ruby for the project we’re working on. This isn’t so much a problem at the beginning, but once we work on one or two different projects that use different versions of Ruby it’s helpful to be able to just switch between versions.

We recommend using a version manager in order to be able to use different ruby versions on your system.

There are several version managers available: RVM, rbenv and chruby to name a couple of popular ones. They all solve the same problem and choosing one mostly boils down to personal preference.

A version manager will allow you to use different Ruby versions for different projects, so that you don’t always need to install a new Ruby version whenever you switch to a project that needs a different version. This can even be automated with a file named .ruby-version that contains the ruby version the project expects.

Testing Tools

For testing there are basically two options: Minitest or RSpec. Minitest follows the classic xUnit framework approach, whereas RSpec follows the behaviour driven design approach. Both frameworks are equally powerful and it boils down to personal preference which one you pick. In our guides we will be using RSpec as the default testing framework.

Directory Structure

A typical directory structure for a ruby command line project consists of a lib directory that contains all source files and a spec directory that includes all tests. Another common convention is having a bin directory that may contain executable files to start your application.

We provided a working example of a minimal project on Github.

  • lib
  • spec
  • Gemfile
  • Gemfile.lock

Naming Conventions

File and directory names are in lower case and files match the classes or modules they contain. For example the class Vanilla should be contained in file vanilla.rb.

Tests match their production code file names with a _spec suffix, e.g. tests for code in lib/vanilla.rb should be written in spec/vanilla_spec.rb.

Example Project

The repository for the example applications is available at github.com/vanilla-project/ruby-command-line.

The main application consists of basically three files:

  • bin/example is the main executable that instantiates and runs:
    • lib/main.rb contains the main application that uses:
      • lib/example.rb which contains only one method that returns a string.

Running the Application

To run the application we can execute bin/example. This should print the text “Ruby Example”.

$: ./bin/example
Ruby Example

Running the Tests

To run the tests we execute bundle exec rspec which then looks for all files inside directory spec and runs them. The output should look like the following:

$: bundle exec rspec
..

Finished in 0.00469 seconds (files took 0.07548 seconds to load)
2 examples, 0 failures

Testing Approach

The test for class Example is only verifying the return value of one method.

Main on the other hand is tested via a test-double that gets injected. This allows us to spy on the output of it. We want to avoid printing anything to the screen while running the tests. Injecting a test double in this instance is a nice way to isolate our application from the command line.

In the executable bin/example we then inject $stdout, which is Ruby’s variable for its standard output.