Wow, this video is awesome!

A must see indeed. Specially if you don’t believe in it.

Got ya!

Advertisements

Metaprogramming Ruby

There are thousands of books that will take you from illiterate to novice in any programming language. But finding those that will take you from novice or intermediate to expert is hard. I remember reading Effective Java some years ago and wishing I had something like that for Python. I’ve never found one.

Metaprogramming Ruby is a great book full of very interesting knowledge, full of those things that separate a Ruby programmer and an export Ruby programmer. Before finishing the book I’ve already put to use some of the lessons and it saved me a lot of time. The book payed for itself before I’ve finished reading and I really recommend it to anyone who is serious about coding in Ruby.

360 vision

I’m surprised I’ve never seen this idea being tried…

When I’ve was a kid I’ve read a report about an experiment. A guy put goggles with screens so that he could see nothing but the screens (ala virtual reality). The same device also had one or two cameras and the screens projected an upside-down image of the camera(s). After a while (I remember three days) of bumping into furniture, walls and eventually the floor, the guy stopped noticing the images were upside down. The brain switched to interpret the new images.

When they removed the goggles, suddenly everything was upside down and the brain took the same amount of time to switch back.

I’ve immediately got this idea: let’s put cameras all around the head in a helmet and let’s compress the 360 image into the two screens. At first we’ll be very confused but after a while we’ll be able to see 360. Wouldn’t it be great?

The magic of Bundler

Recently I reported a bug for Formtastic. Justin French, the author of Formtastic, created a branch and made a fix. He then asked me for my feedback.

I look at the code and then decided to give it a try. In a pre-Bundler world that would have required this:

  1. Find a directory to play with this.
  2. Clone the Formtastic repository with Git from http://github.com/justinfrench/formtastic.git
  3. Create a local branch tracking the remote branch with the fix, GH-264. This is something I don’t do often enough with Git and every time I have to look it up.
  4. Figure out how to build a gem out of it. Is it rake? is it rake build? is it rake gem? This might also fail and need fixing some stuff.
  5. Install said gem, which is not that trivial. Should I install as my user or as root? Should I remove the currently installed version of the gem? If the branch didn’t have an increase in version number it could be problematic.
  6. Test my application. Make sure it’s picking up the new gem.
  7. Uninstall the gem, maybe re-install the stock gem.
  8. Delete the temporary directories I’ve created to hold the cloned repository (this is something I always forget to do and a month later I’m wondering: what’s this? is there any important changes I’ve did in this repo?).
  9. The tasks are not that big, but are very inconvenient to do and uncomfortable for a perfectionist like me. Thankfully I’m using Bundler, so the above was like this:

  1. Add :git => "http://github.com/justinfrench/formtastic.git", :branch => "GH-264" to the Formtastic line in Gemfile.
  2. Run bundle install.
  3. Test app.
  4. Revert the Gemfile change.
  5. Run bundle install.
  6. I really love Bundler.

Redirecting back

It’s very common in Rails CRUD to have a create and update actions that redirect back to the show action. The idea is that you show an object, click edit, save, go back to showing said objects with your changes.

All is fine until you have an edit link somewhere else. Let’s say you have an edit link in the listing of the CRUD, when someone uses you have to go back to the listing, not the show.

Well, Ruby on Rails provides just the thing for that:

redirect_to :back

That will send you back wherever you came from. The problem with that is that it will raise an exception if there’s no HTTP_REFERER, so you’ll have to write something like this:

begin
  redirect_to :back
rescue ActionController::RedirectBackError
  redirect_to somewhere_else
end

Of course there’s a pattern, so almost all my projects, at one time or another end up with this snippet of code in the application controller:

def redirect_back_or_to(*args)
  redirect_to :back
rescue ActionController::RedirectBackError
  redirect_to *args
end

I really like how every method is an implicit begin, it really looks beautiful. Then you just do:

redirect_back_or_to somewhere_else

I’m surprised Rails didn’t come with something like that out of the box, or maybe I just missed.

fofof was useless

It’s always hard to kill your own code, but not killing it when you have to is worst in the long run. My idea for fof and consequently my gem fofof was useless.

First I’ve discovered it didn’t work at all with the new Rails 3 query syntax. When I started to find a fix I’ve discovered I could replace the whole thing with:

 || raise(NotFound.new)

The examples in the Find or 404 post would end up like:

Blog.find_by_id(id) || raise(NotFound.new)

and

blog = Blog.fof.find(blog_id)
post = blog.posts.find_by_id(id) || raise(NotFound.new)

It’s less code, it’s more robust, I even think it’s much more readable. So there you, I’m killing fofof.

Sharing my code

I’ve recently wrote several posts that contiained code to copy and paste:

I don’t like copying and pasting code and since I was already doing it between several of my projects, I took those pieces of code and package them as gems. If you want, you can use them too:

I find it really awesome how many times some of my gems were downloaded:

Update: fofof is actually useless.

Generating sample data

As I’ve said in previous posts, I like being able to generate sample data for the projects I’m working on very quickly. It allows new developers to get up to speed fast, and new developers to move faster.

When I don’t have a sample data generation method, I’m always scare to try whether, for example, deleting a project deletes all the todos in a project tracking system. Simply because I’ll have to generate that project and all todos by hand. Many times I end up not testing those destructive actions as often as I should.

The other reason while having a stable set of sample data is that you start to know it: “Hey! the users Paul and John are supposed to be on the same team, why I am not seeing them together? Something is broken”. To help with that I also use data that we already know. If I have teams with members I would create one team with John, Paul, George and Ringo called Beatles and another with Freddie, Brian, Roger and John called Queen. If you see Paul next to Freddie, something is broken.

To generate the sample data I use factories; which I also use to test instead of fixtures. If you are not familiar with factories, please, stop reading and go to check factory girl. I don’t care if you never come back to this blog if you start using factories instead of fixtures. Factories is so much better! But that’s probably repeated a thousand times over the web, so I’m not going to go into details.

In lib/tasks/data.rake I end up creating:

namespace :db do
  desc "Generate sample data for developing"
  task :sample_data => :environment do
    destroy_data()

    puts "==  Data: generating sample data ".ljust(79, "=")

    beatles = Factory.create :team, :name => "The Beatles"
    Factory.create :user, :name => "John Lennon", :team => beatles
    Factory.create :user, :name => "Paul McCartney", :team => beatles
    Factory.create :user, :name => "George Harrison", :team => beatles
    Factory.create :user, :name => "Ringo Starr", :team => beatles

    queen = Factory.create :team, :name => "Queen"
    Factory.create :user, :name => "Freddie Mercury", :team => queen
    Factory.create :user, :name => "Brian May", :team => queen
    Factory.create :user, :name => "John Deacon", :team => queen
    Factory.create :user, :name => "Roger Taylor", :team => queen

    puts "==  Data: generating sample data (done) ".ljust(79, "=") + "\n\n"
  end
end

For the implementation of destroy_data look at Deleting all records in a Rails project.

The problem with doing that with factories is that it is too silent. I like knowing what’s going on and for new developers it’s good to get a glimpse of the data. All users have the same password so after rake db:sample_data finishes, a new developer already know what email and password to use to log in. If you want to make it even easier, you can print out the password doing sample data generation.

The password is of course defined in the user factory:

Factory.define :user do |user|
  user.email { Factory.next :email }
  user.password "testing"
  user.password_confirmation "testing"
end

To be able to make factories verbose I created VFactory (for Verbose Factory of course) that you use just like Factory, but it prints out everything. This is its code:

# Verbose factory.
module VFactory
  def self.create *args
    human_factory_name = args.first.to_s.gsub("_", " ")
    if args.size > 1
      human_arguments = args.second.map { |name, value| "#{name}=>#{value.is_a?(Array) ? value.join(", ") : value}" }.to_sentence
      puts "-- creating #{human_factory_name} with #{human_arguments}."
    else
      puts "-- creating #{human_factory_name}."
    end
    Factory.create(*args).tap do |obj|
      puts "   -> done: #{obj}"
    end
  end
end

The output of this is more or less like this:

==  Data: generating sample data ==============================================
-- creating team with name=>The Beatles.
   -> done: #
-- creating user with name=>John Lennon and team=>#.
   -> done: #
-- creating user with name=>Paul McCartney and team=>#.
   -> done: #
-- creating user with name=>George Harrison and team=>#.
   -> done: #
-- creating user with name=>Ringo Starr and team=>#.
   -> done: #
-- creating team with name=>Queen.
   -> done: #
-- creating user with with name=>Freddie Mercury.
   -> done: #
-- creating user with with name=>Brian May.
   -> done: #
-- creating user with name=>John Deacon.
   -> done: #
-- creating user with name=>Roger Taylor
   -> done: #
==  Data: generating sample data (done) =======================================

If you are wondering why my objects look so pretty when printed, that’s because I always define a to_s for all models that contain the id and other important data. In this case it would be:

def to_s
   ""
end

That’s very useful for debugging. I also try to always have a name method in my models that give me something that represents the object and that I can show to the users.

The next step in data awesomeness would be, with one command, being able to download and import all production data. This really helps reproducing and debugging reported issues; specially when those issues are related to destructive changes.

Update: this is now a gem.

Find or 404

There’s a pattern I use often: find a record or throw a 404. In my Rails apps that means literally throwing a 404 exception. After hard-coding that logic in my controllers countless times, I’ve decided to abstract it out and this is how it works. Instead of:

Blog.find(id)

you now do

Blog.fof.find(id)

It also works for associations:

blog = Blog.fof.find(blog_id)
post = blog.posts.fof.find(id)

Fof stands for “Find or Four oh four”. The code to accomplish that is:

class NotFound  e
    if arguments.last.is_a? Hash
      arguments = arguments[0..-2].inspect[1..-2] + ", " + arguments.last.inspect[1..-2]
    else
      arguments = arguments.inspect[1..-2]
    end
    raise NotFound.new("Not found: #{@model.name}.#{method}(#{arguments}): #{e.message}")
  end
end

class ActiveRecord::Base
  def self.fof
    @_fof ||= FOF.new(self)
  end
end

Now that I think about it, I could have called it fofof.

Update: this is now a gem.

Update: this is actually useless.