Understanding Ruby Rake

I highly recommend you watch Jim Weirich’s talk about Basic Rake, because he describes rake so beautifully and this is my attempt to document how I understand his explanation.

What is Rake?

Rake is a task execution engine that helps you organize and execute tasks in a ruby or rails environment. Rake is pure ruby, so anything you can do in ruby, you can do in rake.

How to write rake?

  1. Rake tasks are written in a file in the root of your project, called: Rakefile
  2. A rake task has a title, which can be a string or symbol.
    task :make_tea # Correct rake title
    task "make_tea" # Correct rake title
  3. A rake task has an action which executes inside a do..end block.

    task :make_tea do
    puts "Making Hot Cup of Tea"
    end
  4. A rake task can have dependencies, which are executed before the task.

    task :make_tea => [:boil_water, :add_teabag] do
    puts "Making Hot Cup of Tea"
    end

    task :boil_water do
    puts "Boiling water"
    end

    task :add_teabag do
    puts "Put Teabag in Cup"
    end

You run tasks in the command line. To run the make_tea task in our Rakefile, you issue this command;

rake make_tea

The above command will look for the make_tea task in our Rakefile, check it’s dependencies and see that it depends on boil_water and add_teabag tasks, it will run boil_water first, then run add_teabag before it runs make_tea. So our output will be;

"Boiling water"
"Put Teabag in Cup"
"Making Hot cup of Tea"

In a situation where multiple tasks have the same dependency, the first time rake encounters the dependency, it executes it, when it encounters the dependency the second time, rake already knows it’s been executed so it doesn’t execute it again.

To run rake without specifying a particular task, just define a default rake task at the top of your Rakefile and give it a task to run, e.g. task :default => :make_tea, then in your command line run rake, this will output;

"Boiling water"
"Put Teabag in Cup"
"Making Hot cup of Tea"

If you have rake tasks that might conflict because they share the same rake name, you can use namespaces. E.g.

task :boil_water do
  puts "Boiling water"
end

namespace :coffee do
  task :boil_water do
    puts "Boiling water for coffee
  end
end

You invoke the namespace in your command line like so: rake coffee:boil_water, this will output "Boiling water for coffee". And when you do rake boil_water, the output is "Boiling water"

Helpful rake commands

rake -P will output all the rake tasks and their dependencies in alphabetical order:

rake add_teabag
rake boil_water
rake coffee:boil_water
rake make_tea
    boil_water
    add_teabag

rake -T will output the rake commands and their attached documentation. Documentation can be added to rake tasks using the desc keyword written above the rake task. E.g.

desc "Boil water for making tea"
task :boil_water do
  puts "Boiling water"
end

If you run rake -T, it outputs:

rake boil_water  # Boil water for making tea

rake -W task_name will tell you the exact file location of the rake file and the line number the task is defined in. This command only works with documented tasks.

rake -W boil

The above command tells rake to show the file location and line number of every task that has in its title, a boil.

rake boil_water           ../Rakefile:9:in
rake coffee:boil_water    ../Rafefile:14:in

Ruby Kata Two (First Approach)

The coding kata is a way to get programmers practicing their craft just like musicians and martial artists do by: “applying the theory over and over again, using feedback to get better every time“. You can read more about coding katas here.

The binary chop, the second kata in the series, tasks the programmer to implement a binary search routine using 5 different methods. A binary search is a way to find the position of a value (key) within a sorted array of values.

Example, given an array_values = [1, 2, 4, 6, 8] with a key = 6, the method should return 3 when the array_values and key variables are passed in as arguments of the method, if the key can’t be found, the method should return -1. A quick implementation in ruby can be seen below.

This is one of the sweetness of ruby, however this defeats the purpose of the kata, which is to make the programmer implement the solution. Below is my first solution to Kata 2, I will appreciate your feedback.

Here are the test cases which all pass.