Ruby Fleebie

Rediscovering the joy of programming

Should ruby go the haml route and uses significant whitespaces?

Before I start, let me get something straight: I’m not saying it would be a good or bad idea… I’m just asking the question.

I must say that my first experience with a significant whitespace language was a disaster. The first time I had to use Python was on a server via ssh. I was in a hurry and wanted to monkey patch some buggy script I had installed. So without thinking too much I opened the script with a text editor called nano. The problem is that a TAB in nano produces between 173 and 177 white spaces. Realizing this I decided to refrain from indenting one line or two because it was too ugly and unreadable. Then python told me that I could not do this… and at the time I remember thinking it was unacceptable that a script start to malfunction just because of a few missing whitespaces. Anyway, I spent some long minutes trying to fix a few indentation issues (in nano! I still didn’t realize it was the source of the problem) and it was very tedious. Had I try debugging the python script on my local computer with gedit for example, things would surely have turned out differently.

Then Haml came… and I stayed away

This unpleasant experience I had with Python had a rather negative side effect: It made me completely ignore Haml for a long time, which is sad because it is such a great alternative to erb.

But now I use Haml, and I really like it. Not having to “close my tags” is more satisfying than I thought it would be. I always delight when I realize I was about to write a “- end” tag to close a “- @items.each” loop or something like that. I don’t have to! Less typing, less noise, cleaner, prettier, I love this! Wouldn’t be nice if we could do away with the “end” keyword in ruby as well?

Just to give us an idea, here is how an actual class from the Haml gem would look like if it was written in Significant Whitespace ruby:

    class ParseNode < Struct.new(:type, :line, :value, :parent, :children)
      def initialize(*args)
        super
        self.children ||= []

      def inspect
        text = "(#{type} #{value.inspect}"
        children.each {|c| text << "\n" << c.inspect.gsub(/^/, "  ")}
        text + ")"

Great, it sill looks like ruby. We just removed some noise to make it even more readable.

Let’s convert a longer method, still from the Haml gem, to see how it would look like:

    def parse_new_attributes(line)
      line = line.dup
      scanner = StringScanner.new(line)
      last_line = @index
      attributes = {}

      scanner.scan(/\(\s*/)
      loop do
        name, value = parse_new_attribute(scanner)
        break if name.nil?

        if name == false
          text = (Haml::Shared.balance(line, ?(, ?)) || [line]).first
          raise Haml::SyntaxError.new("Invalid attribute list: #{text.inspect}.", last_line - 1)

        attributes[name] = value
        scanner.scan(/\s*/)

        if scanner.eos?
          line << " " << @next_line.text
          last_line += 1
          next_line
          scanner.scan(/\s*/)

      static_attributes = {}
      dynamic_attributes = "{"
      attributes.each do |name, (type, val)|
        if type == :static
          static_attributes[name] = val
        else
          dynamic_attributes << inspect_obj(name) << " => " << val << ","

      dynamic_attributes << "}"
      dynamic_attributes = nil if dynamic_attributes == "{}"

      return [static_attributes, dynamic_attributes], scanner.rest, last_line

Well, not bad at all… the only problem is that the loop is quite long and I had to double-check to know if the “static_attributes” statement was part of the loop or right after. This kind of double checking could get on my nerves fast.

I’m still undecided. I dislike end tags but they can clear things up sometimes. Anyway, I guess we probably never see this implemented in ruby. What’s your thoughts on significant whitespace languages?

Review of some testing tools for ruby

I never wrote anything about tests on this blog and the reason is simple: I never considered testing to be something fun. The little slogan you see at the top left (a bit cheesy I admit) is the reason why I started Ruby Fleebie back in 2007. I was amazed by the possibilities of the ruby language and the way you could express complex stuff in a very concise an elegant manner.

Now does this mean I don’t write tests just because I think they aren’t fun? Of course not. I do write tests… I just don’t blog about them because they don’t excite me very much. I’m currently on a quest to find a way to enjoy testing more. This is a work in progress for me and so far I have managed to draw at least this conclusion: To enjoy testing a bit more, one need a killer setup and great testing tools to work with.

Continuous testing

Running “rake test” once in a while is a very simple setup. The biggest problem with this approach is that it disconnect you from your “flow”. You have to remember about running this command and if you forget (I know I do) no one will know about it.

So a part of the solution to improve my testing setup was to have my tests run continuously. The most popular library that help with this is probably autotest. It fixes once and for all the problem of forgetting to run my tests.

So we have autotest running our tests in the background. That’s great… but it could be better. the output that Test:Unit or RSpec spits is verbose, hard to read and hidden somewhere on a terminal window. I wanted the testing phase to be integrated as much as possible into my other programming tasks, so I decided to install autotest-notifications, a nice autotest plugin that knows how to talk to libnotify (linux), growl (mac) or snarl (windows) and it tells you if you have failing tests. This is the kind of OS integration I like! I am a Linux guy so I had to install libnotify-bin in my ubuntu box before I could use the plugin. Mac users will have to make sure growl and growlnotify is installed on their machines. As for windows users, they will have to install snarl. Here is a screenshot showing how it looks in Linux :

To start autotest-notifications, type an-install. To stop, type an-uninstall.

Other testing tools

Now that my tests run continously, I can concentrate on finding other testing tools that will help me write tests more easily and more rapidly.

Test::Unit / RSpec

I always used Test::Unit. I tried RSpec for the first time very recently and was quite pleased with it. I don’t see that much difference between the two except in the syntax. The only thing I can say is that when I use Test::Unit, I absolutely want to use Shoulda as well. When I use RSpec, shoulda is less essential but I still use it.

Shoulda

I’d say that shoulda is Test::Unit best friend. It gives you a nice set of useful test macros and some great semantic constructs that will improve the readability of your tests.

Capybara (I give to this one the gold medal)

Question: What’s missing if I only use Test::Unit or RSpec ?
Answer: A good integration testing framework

Capybara is a great tool for higher level testing. It’s the kind of testing a non-programmer can understand: when I click this link then I should see this and when I fill this form then it should take me there and so on.

Capybara is a magician that will actually click on your links, fill out your forms and even triggers your javascript. He’s like a end-user testing your app in a hidden browser. Seriously I think these tests are great to have and capybara does a wonderful job to help you write them.

Cucumber

To be frank, I find this one more difficult to love. If there’s one tool I plan to stop using in the near future, it’s probably cucumber. But to each its own!

For those who don’t know, Cucumber is a DSL that encourages Behaviour Driven Development. It lets you describe features before you start implementing them. The “twist” is that you describe these features in plain english, or I should rather say, in plain Gherkin. You then take each “plain Gherkin” instruction and you translate them into ruby code in another file called a “steps definition file”. For example:

Gherkin:

Given a user called Bob
When he stumbles and fall flat on his face
Then he should lose only 1 tooth

Step definition file:

Given /^a user called (.*)$^ do |user_name|
  @user = User.create(:name => user_name)
end

When /^he stumbles and fall flat on his face$/ do
  @user.stumble_and_fall!
end

Then /^he should lose only (\d+) (tooth|teeth)$/ do |count|
  @user.teeth_lost.should == count
end

My problem with Cucumber

I am the co-founder of a startup composed of 2 developers. We obviously don’t need something like the business friendly Gherkin language. For us this language is harder to understand than ruby code can be. Of course, when it’s some dead easy stuff like the example above, it looks cool, but when you start adding fixtures/factories into the mix and that you have several words in the expression that will be replaced in a regex later, then you begin to write features filled with black magic and you won’t want to touch them ever again because you know that a single tiny change will break them. For each Gherkin line I’m writing, I can’t refrain myself from thinking about the step definition that I will have to create for it. That is the main problem I have with Cucumber. As a developer I cannot write Gherkin like it was only plain english. So I often write what we could call technical gherkin easy to translate in a regex-friendly step definition… and sometimes this kind of technical language is a lot harder to appreciate than ruby. Even worse, writing this kind of developer-friendly Gherkin destroys the purpose of this language.

Factory Girl

This one gem will save you a lot of time… once you know how to use it!

What is Factory Girl? It’s simply a way to replace the somewhat cumbersome fixtures in Rails. You can see it this way: Instead of having a bunch of “static” data that will be loaded in your database everytime, with FactoryGirl you build ActiveRecord objects on the fly depending on your testing needs. Basically, you have to define one factory per model. In each factory, you define default values for every attributes you want (generally those that cannot be nil). These values will always be used unless you specify something different in your tests.

Factory.define(:league) do |l|
  l.name "The happy league"
end

Factory.define(:season) do |s|
  s.starts_on Date.parse("2010/11/30")
  s.ends_on Date.parse("2011/02/18")
  s.association :league
end

Factory.define(:gameday) do |gd|
  gd.season {Season.first || Factory(:season)}
end

Factory.define(:team) do |t|
  #sequences are a good way to generate unique values
  t.sequence(:name) do |n|
    "The big fat tigers - #{n}"
  end
  t.season {Season.first || Factory(:season)}
end

Factory.define(:game) do |g|
  g.game_time DateTime.parse("7:00 PM")
  g.association :gameday
  g.association :team_a, :factory => :team
  g.association :team_b, :factory => :team
end

If I want to test something with a Game instance and I don’t really care about the other associated models, then I can simply write Factory(:game) and FactoryGirl will take care of creating all the associations for me. I don’t have to create a gameday then associate it to my game… then create a season and associate it to my gameday… then create a league and associate it to my season. I can just type Factory(:game) and I will have a perfectly valid Game instance with all its associations.

I want to bring your attention on line #12 and #20. The way I define my association for the season factory is different. There is probably a better way to do this but I didn’t find any. Basically, instead of going the traditional route and do this:

gd.association :season

I use a block to specify a condition. I do this because of the Game factory defined at line #23. You can see that I have a relation to the Gameday factory and two relations to the Team factory. Both these factories are associated with the Season factory. If I had made a standard association call (i.e. gd.association :season and t.association :season), three different seasons would have been created at line #25, #26 and #27. This is not what I wanted… I wanted the same season to be used.

FactoryGirl is a great fixture replacement, but as you see it got its quirks and it’s not the easiest tool to use.

Conclusion

So, am I a happy tester now? not yet, I’m afraid… but I’m getting there I guess. Feel free to leave me a comment and tell me which tools you use and how you integrate testing in your programming routine.

Interacting with MongoDB using Rails 3 and MongoMapper

MongoDB is an opensource document-oriented database in the vein of CouchDB. It’s been a while since I wanted to try this kind of database on a Rails project. After reading this nice tutorial today I decided to take some time to create a sample Rails 3 app and put it on github.

I chose to use MongoMapper, a ruby object mapper for Mongo. MongoMapper uses ActiveModel and let you interact with a MongoDB database in a very ActiveRecord way.

Hope this sample app will help you getting started with MongoDB!