Getting my bearings with ruby

I come from a mavenized world.

A world where a project’s structure and dependencies are well specified in a model and where that model, Maven and the Java SDK are everything I need to build a project anywhere. Maybe there’s some things wrong with Maven; I think this is one of the things where it excels.

So when I play with other languages, my tendency is to look for the Maven Metaphor, the Maven equivalent to define a project, build it and have its dependencies resolved, hopefully from an all-knowing internet entity.

I felt in heaven when I found Leiningen for Clojure, but I almost cried when I found weird things for C#  and ugly things things for C++.

And now I’ve been learning Ruby – a language that follows that principle of least astonishment… Seriously Ruby, you’re messed up. Here’s how I understand the Ruby world of project management / dependency management so far:

So, a common practice seems to be to use Rake to build the project and Gems to distribute it. Rake is like Make. But for Ruby. And Gems are like Maven artifacts.

But then, it seems like the best way to use these two things together is by means of another tool – Bundle.

Ao, let’s imagine a system where you have Ruby, Gem, Rake and Bundle installed. The (rough) equivalent to mvn archetype:generate would be bundle gem bloguito.

This will create a directory structure with some not very obvious things:

  • Gemfile – this would normally be where you would put your project’s dependencies. Except your won’t because it will point to the gemspec, a way of saying “dependencies are all in bloguito.gemspec“;
  • bloguito.gemspec – this is where you have information about your project as well as dependencies and is the closest we get to a pom.xml file except it isn’t. Because it does not define any project build phases;
  • Rakefile – this is where your build phases would be defined. By default this includes something called gem_tasks, which is a set of default tasks like build, install and release, kind of equivalent to mvn compile, mvn install and mvn release:prepare + mvn release:perform;
  • ./lib – and finally, your code should go in this directory.

So, somewhat different from Maven, in that Maven tries to do everything and here each tool does one thing and one thing only. Not worse nor better; just different.

Now, what is definitely good is that this seems to be an accepted standard for building Ruby applications – in RubyMine, if you create a new project, this is exactly the structure it will have:

/Users/Luis/.rvm/gems/ruby-2.0.0-p0@global/bin/bundle gem untitled
create bloguito/Gemfile
create bloguito/Rakefile
create bloguito/LICENSE.txt
create bloguito/
create bloguito/.gitignore
create bloguito/bloguito.gemspec
create bloguito/lib/bloguito.rb
create bloguito/lib/bloguito/version.rb
Initializating git repo in /Users/Luis/dev/bloguito

You can always count on JetBrains.