ruby koans is awesome

Mar 30, 2010

Note: The creators of Ruby Koans, Edgecase, has created a wonderful Ruby Koans website. Check it out.

Ruby Koans is a set of tests to teach you the Ruby language. I’m impressed how much I’m learning from these tests and right off the bat, it’s using Test::Unit which gives you an introduction to TDD style coding.

How to get started

The README.rdoc at Ruby Koans GitHub repo should suffice, but if that wasn’t clear, you should have the following already installed:

Basically, do a git clone on the Ruby Koans repo (or download zip file):


git clone git://github.com/edgecase/ruby_koans.git
Initialized empty Git repository in E:/p/git/fake/ruby_koans/.git/
remote: Counting objects: 294, done.
remote: Compressing objects: 100% (286/286), done.
remote: Total 294 (delta 184), reused 0 (delta 0)
Receiving objects: 100% (294/294), 51.84 KiB, done.
Resolving deltas: 100% (184/184), done.
Done. Get out your favorite editor (or IDE) and have a command prompt shell or two ready. You want to first run path_to_enlightenment.rb:

ruby path_to_enlightenment.rb

Thinking AboutAsserts
  test_assert_truth has damaged your karma.

You have not yet reached enlightenment ...
<false> is not true.

Please meditate on the following code:
./about_asserts.rb:10:in `test_assert_truth'
path_to_enlightenment.rb:28


mountains are merely mountains

Open about_asserts.rb and look up the test method called test_assert_truth and fix whatever is wrong with it. The tests will give you hints, so don’t worry, you’ll figure it out. Once you do, save the file, re-run path_to_enlightenment.rb.


ruby path_to_enlightenment.rb

Thinking AboutAsserts
  test_assert_truth has expanded your awareness.
  test_assert_with_message has damaged your karma.

You have not yet reached enlightenment ...
This should be true -- Please fix this.
<false> is not true.

Please meditate on the following code:
./about_asserts.rb:16:in `test_assert_with_message'
path_to_enlightenment.rb:28


learn the rules so you know how to break them properly

You will now see that test_assert_truth has expanded your awareness. Now go on to the next test and fix the problem in there. Rinse and repeat.

If you ever get up to about_scoring_project.rb, please let me know how you implemented the score method. Here’s mine:


def score(dice)
  total = 0
  rolls = dice.dup
  return total if rolls.size == 0
  (1..6).each do |i|
    if rolls.count(i) >= 3
      3.times do
        rolls.delete_at(rolls.index(i))
      end
      total += (i == 1) ? 1000 : 100*i
    end
  end
  rolls.each do |i|
    if i == 1
      total += 100
    elsif i == 5
      total += 50
    end
  end
  total
end

I added additional tests just for the heck of it:


  def test_other_oddities
    assert_equal 1100, score([1,1,1,1])
    assert_equal 1200, score([1,1,1,1,1])
    assert_equal 600, score([5,5,5,5,5])
  end

Here’s my Proxy class from about_proxy_object_project.rb:


class Proxy
  attr_reader :messages

  def initialize(target_object)
    @object = target_object
    @messages = []
  end

  def method_missing(method_name, *args, &block)
    @messages.push(method_name)
    @object.__send__(method_name, *args)
  end

  def called?(message)
    return true unless @messages.index(message).nil?
    false
  end

  def number_of_times_called(message)
    return @messages.count(message)
  end
end

Have fun!