home icon contact icon rss icon last FM icon facebook icon LinkedIn icon Delicious icon twitter icon

Archive pour le mot clé Ruby

RVM tips - Tell me my ruby version !

Now that Rails 3 is out, I'm starting to use it on recent application. But I also have some work to do on older applications from time to time.

The first annoying thing is that older applictions are built for Ruby 1.8.6 and Rails 3 works with Ruby 1.9.2. The other thing is that the rails command is radicaly different from Rails 2.3.8 to Rails 3.

Using RVM, I'm able to easily switch from one Ruby version to another and from one gems configuration to another. And this depending on the shell I am on.

The counterpart of this is that I'm very confused and never know on which configuration my shell is currently. So I needed a clear way to know it. It would be great if the prompt can tell it to me. Here is how to do that with bash :

# Copy this in ~/.bashrc
    __ruby_ps1 ()
    {
        local g=`ruby -v | cut -d' ' -f2`

        if [ -n "$1" ]; then
            printf "$1" "${g}"
        else
            printf "(%s)" "${g}"
        fi
    }

    export PS1='\u@\h$(__ruby_ps1):\w\$ '

Timezone, one of the developer's plagues

Timezones, along with charset and multi-browser support, are a pain in the ass to deal with.

With rails, since 2.1, timezones are supported by default via the config.time_zone option :

# config/environment.rb
config.time_zone = ‘UTC’

You can configure it to something else like :

# config/environment.rb
config.time_zone = 'Paris'

Or in the controller, per user basis :

# controllers/application.rb
before_filter :set_time_zone

def set_time_zone
    Time.zone = @current_user.time_zone if @current_user
end

With all this, rails and active record handle timezones for you. But be very careful when building SQL queries by hand.

ActiveRecord converts dates to UTC timezone before saving them to the database, and convert them back to the current timezone when you load the record from the database. And this can lead to something strange when doing queries like:

User.all(:conditions => ["created_at > ?", Date.today.at_beginning_of_day])

ActiveRecord converts date, but only when saving or loading records. But you can deal with it if you don't forget timezones:

User.all(:conditions => ["created_at > ?", Time.zone.now.at_beginning_of_day])

Something strange is that Rails adds timezone support to the Time class, but not to the date calculations:

>> Time.zone = 'Paris'
>> Date.today.to_s(:db)
=> "2010-02-05"
>> Time.now.to_s(:db)
=> "2010-02-05 00:07:49" # The same date everywhere
>> Time.zone.today.to_s(:db)
=> "2010-02-05"
>> Time.zone.now
=> Fri, 05 Feb 2010 00:06:13 CET +01:00 # All is right here

Let's make some calculations :

>> Time.zone.today.at_beginning_of_day.to_s(:db)
=> "2010-02-05 00:00:00" # Seems to be ok, but
>> Time.zone.now.at_beginning_of_day.to_s(:db)
=> "2010-02-04 23:00:00" # Woot ! the database is still yesterday !

Something you can do if you absolutely need to use Time.today (something stolen from Barry Hess):

class ::Date
  def beginning_of_day_in_zone
    Time.zone.parse(self.to_s)
  end
  alias_method :at_beginning_of_day_in_zone, :beginning_of_day_in_zone
  alias_method :midnight_in_zone, :beginning_of_day_in_zone
  alias_method :at_midnight_in_zone, :beginning_of_day_in_zone

  def end_of_day_in_zone
    Time.zone.parse((self+1).to_s) – 1
  end
end