Category: Technical

Posts related to programming or other highly technical stuff that can only be of interest to computer geeks.

  • When I need to run something periodically on production, I always implement it as a rake tasks and install it as a cron job. Nevertheless there’s some setup to do in the task to have proper logging and error reporting.

    This is the template I use for creating those tasks:

    namespace :projectx do
      desc "Do something"
      task :something => :environment do
        if Rails.env.development?
          # Log to stdout.
          logger = Logger.new(STDOUT)
          logger.level = Logger::INFO # DEBUG to see queries
          ActiveRecord::Base.logger = logger
          ActionMailer::Base.logger = logger
          ActionController::Base.logger = logger
        else
          logger = ActiveRecord::Base.logger
        end
    
        begin
          logger.info "Doing something"
        rescue Exception => e
          HoptoadNotifier.notify(e)
          raise e
        end
      end
    end

    While in development mode, it outputs to the console for convenience.

  • For a personal project I’m working on, I need to find out the smallest time period with more than 5 records. I essentially wrote this code:

    period = [1.week, 1.month, 1.year].select_first do |period|
      Record.where("published_at >= ?", period.ago).count >= 5
    end
    

    only to find out that the select_first method doesn’t exist. So I wrote it:

    module Enumerable
      def select_first(&predicate)
        self.each do |item|
          if yield(item)
            return item
          end
        end
        return nil
      end
    end
    

    and then of course, I tested it:

    require "test_helper"
    
    require "enumerable_extensions"
    
    class EnumerableTest  2 }
      end
    
      should "select_first the first one" do
        assert_equal 1, [1, 2, 3, 4].select_first { |i| i >= 1 }
      end
    
      should "select_first the last one" do
        assert_equal 4, [1, 2, 3, 4].select_first { |i| i >= 4 }
      end
    
      should "select_first none" do
        assert_equal nil, [1, 2, 3, 4].select_first { |i| i >= 100 }
      end
    end
    
  • I’ve just released another gem, this one extends Hash to contain another method called hmap. This solves a problem I face ofter: how to run a map in a hash that returns another hash, for example:

    {:a => 1, :b => 2, :c => 3}
    

    being converted into

    {:a => 2, :b => 3, :c => 4}
    

    With hmap it’s easy:

    hash.hmap { |a,b| {a => b + 1} }
    

    It also works with arrays, but you must make sure the array you return always contains two and only two elements:

    hash.hmap { |a,b| [a, b + 1] }
    

    And that’s all, quite a simple piece of code, but now it’s re-usable and well tested.

  • I think this partnership with Microsoft was a mistake for Nokia. It was great for Microsoft though.

    Every time you show an old Nokia phone you get the same comment: “Oh, those phones were built to last, I went through 3 iPhones and the Nokia still works…” or “That is the only phone that will not blend”.

    But Nokia’s obsolete software is killing it. They need to provide truly smartphones. They had three options:

    • build their own
    • use Android
    • use Windows

    I think they already tried to build their own and failed. That’s very hard. A giant like Microsoft tried to build their own and failed. It’s very hard to build a software platform.

    Apple did it by being the first ones and providing the coolest product ever. Google did it by doing it for free. They are both a success because they have thousands and thousands of applications on their platform by now.

    Microsoft haven’t done it. As powerful as Microsoft is, they still haven’t cracked the smartphone market, and it’s very likely they’ll never do. They are up against Apple and Google and both of them have years of advantage now (previous efforts by Microsoft are useless today).

    Now Microsoft has a chance to do it because of the deal with Nokia. Nokia is likely going to put Windows 7 Phone whatever on the hands of many people. Those people will get use to Windows, but not to Nokia and may switch to HTC or another provider in a blink of an eye. Microsoft wins, Nokia loses.

    I think Nokia should have done with Android. I know it’s hard to differentiate yourself with Android (what’s the different between a Samsung and a Sony/Ericson phone these days? They both run Angry Birds), but Nokia could have done it by making a tough phone. There’s a lot of people today not using smartphones because they won’t last in their pockets. Nokia could build a smartphone for them.

    Maybe Nokia decided against Android because of their past mistakes with Open Source projects and companies. At any rate, I think they are making a mistake right now.

  • Ruby doesn’t have enums and in Rails I sometimes need it. I’ve come out with my own way of doing after some trial and error. First I want to be able to access these enums as constants in a class, like:

    Pizza::RAW
    Pizza::COOKED
    Pizza::BOXED
    Pizza::DELIVERED
    Pizza::EATEN

    That’s actually quite easy:

    class Pizza
      RAW = 1
      COOKED = 2
      BOXED = 3
      DELIVERED = 4
      EATEN = 5
    end

    If I’m storing those values on the database, I’d like to have my database be more readable, so, I just store strings:

    class Pizza
      RAW = "raw"
      COOKED = "cooked"
      BOXED = "boxed"
      DELIVERED = "delivered"
      EATEN = "eaten"
    end

    That’s not very efficient and there are better ways these days. But it’s simple and premature optimization is the root of all evil. Anyway, back to Ruby, I’d like to be able to get a list of all possible enum values, to be able to populate selections for example:

    class Pizza
      RAW = "raw"
      COOKED = "cooked"
      BOXED = "boxed"
      DELIVERED = "delivered"
      EATEN = "eaten"
    
      STATES = [RAW, COOKED, BOXED, DELIVERED, EATEN]
    end

    Simple enough except that it doesn’t follow DRY style. In Ruby we can do better:

    class Pizza
      STATES = [
        RAW = "raw",
        COOKED = "cooked",
        BOXED = "boxed",
        DELIVERED = "delivered",
        EATEN = "eaten"
      ]
    end

    That defines the constant and since the result of RAW = "raw" is "raw" we can also add it to an array at the same time.

    John, the manager of the Ruby Pizza Shop was concerned that some pizzas were devoured immediately and others took as long as 15 minutes. Decided to improve his business he started investigating the whole procedure and he noticed that as soon as the pizza left the kitchen, some cooks considered delivered and marked them as such. That was wrong so instead of doing a pizza-state training, he decided we should improve the UI. Let’s describe the state.

    class Pizza
      STATES = [
        RAW = "raw",
        COOKED = "cooked",
        BOXED = "boxed",
        DELIVERED = "delivered",
        EATEN = "eaten"
      ]
    
      STATE_EXPLANATIONS {
        RAW => "The pizza is not a pizza yet, just a bunch of ingredients.",
        COOKED => "OMG! That smells good!",
        BOXED => "It's ready to go.",
        DELIVERED => "The pizza has been snatched out of the hands of a delivery boy.",
        EATEN => "The pizza is no more."
      }
    end

    Of course we can do better than that and merge it in one:

    class Pizza
      STATE {
        (RAW = "raw") => "The pizza is not a pizza yet, just a bunch of ingredients.",
        (COOKED = "cooked") => "OMG! That smells good!",
        (BOXED = "boxed") => "It's ready to go.",
        (DELIVERED = "delivery") => "The pizza has been snatched out of the hands of a delivery boy.",
        (EATEN = "eaten") => "The pizza is no more."
      }
    end

    Stylistically I’m not a fan, but semantically, that’s dryer. Now, we can get the list of states like this:

    Pizza::STATE.keys
  • 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.

  • 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.

  • 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.

  • 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.