Ruby Koans
RubyKoans is an excellant approach to learn the Ruby language, syntax, structure, and some common functions and libraries. This also teaches you a testing culture. This requires tests to be fixed in order to progress.
My solutions are available here.
##Development Tweaks
Real time updates
To check the solution, one has to run rake
command everytime to know progress status. Smells like there is a need for automation.
I used kicker which is a lean, agnostic, flexible file-change watcher using OS X FSEvents.
You may add this simple .kick
file to the koans project.
process do |files|
execute("rake")
end
To start,
$ kick
Now whenever you modify any test and save the file, kicker will show you the current status.
Git
To share solutions with everyone, I used git and pushed solutions to Github repo.
Prefill commit message
This project saves all the current progress in .path_progress
file.
Sample file:
0,1,2,2,3,3,4,4,5,5,5,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9,9,9,9,10,10,10,10,10,10,11,11,11,12,12,12,13,13,13,13,13,13,14,14
Whenever a koan is finished, koan number is automatically appended to .path_progress
.
Now trick is to prefill git commit
message with the current progress. I created this prepare-commit-msg
hook to solve this problem.
#!/bin/sh
commitMessage=$(./`git rev-parse --git-dir`/get-progress)
echo "Finish koan $commitMessage\n $(cat $1)" > $1
This hook uses another script get-progress
which prints the current progress(i.e. koan number).
#!/usr/bin/env ruby
PROGRESS_FILE_NAME = '.path_progress'
contents = []
if File.exists?(PROGRESS_FILE_NAME)
File.open(PROGRESS_FILE_NAME,'r') do |f|
contents = f.read.to_s.gsub(/\s/,'').split(',')
end
end
print contents.last
Duplicates in .path_progress
Everytime rake
is run, current progress (i.e. koan number) is added to .path_progress
which leads to unnecessary file changes. This creates further problems when .path_progress
is added to git repo.
Time to fix neo.rb
. Add following code to add_progress
method.
def add_progress(prog)
@_contents = progress
# return if already added to progress
return if prog.to_i == progress.last.to_i