Symbol is greatly used in Ruby programs. It is an object of Symbol class. It represents some strings inside the Ruby interpreter. When you think that the string you are going to create would probably going to be reused somewhere again, then you should consider using symbols. The benefit of Symbol is really performance. During a Ruby program’s execution, as long as the symbol contents are the same, they are actually the same object, so it will refer to the same object in memory. e.g.

user1 = {:name => "Shanison"}
user2 = {:name => "Lin"}

Above codes actually only creates 1 symbol object, 2 strings object and 2 hash objects. Imagine that you are creating a lot of hash, the :name symbol would save a lot of object creation. You can even query all the symbols in your program:

Symbol.all_symbols # return an array of symbols

Enough about the introduction to symbols. What I want to talk about is actually about Hash. When constructing a hash, you would use symbol as the keys quite often. Probably due to this reason, in Ruby 1.9 it introduced a new Syntax for Hash.

user1 = {name: "Shanison"}
user2 = {name:  "Lin"}

At first glance, this looks pretty much like syntax for defining javascript object. Looks great. However, take note that the colon must be right after the key without any space. So it is not exactly the same as javascript object syntax.

user1 = {name : "Shanison"} # This will cause syntax error

This shorten syntax sometimes looks short and sweet when you pass it as a parameters.

server = Server.new(
addr: "192.167.123.1",
user: 'id_'
)
# Compares to Below
server = Server.new(
:addr => "192.167.123.1",
:user => 'id_'
)

However, do note that this syntax only works for symbol keys. So if you want to use strings or numbers as the hash keys, you can’t write the syntax in this way. e.g. Below code would return you error:

user1 = {"name": "Shanison"}  # Give Syntax error
user2 = {1:  "Lin"} # Give Syntax error

You can even mix the syntax when your hash has both symbol and numbers as keys, although the combination looks funny.

user1 = {name: "Shanison", 1 => "one"}

However, when your value is also a symbol, this syntax looks really funny:

user1 = {name: :source}

Due to above reasons, I still prefer the old syntax. It is just an options and personal preference, so there is no right or wrong in which syntax you adopt.

I met one very strange problem today.

Below code is working fine on my local machine under ruby 1.8.7 with nokogiri version 1.5.9:

require 'nokogiri'
require 'open-uri'
require 'net/http'

doc = Nokogiri::HTML(open('http://shareinvestor.com'))
puts doc.text

However above code is giving me problems on production servers with ruby 1.8.7 and nokogiri version 1.5.9. The last line returns empty string instead of the whole html. The only difference between the two servers is the ruby patch levels:

my local machine: ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-darwin10.6.0]
production server: ruby 1.8.7 (2009-3-1 mbari 8B/0×8770 on patchlevel 72) [i686-linux]


So I thought the open-uri.rb might be different, checking the open-uri.rb found out that they are exactly the same. So I can’t think of any cause that is causing this problem.

Anyway below is the fix if you met this issue. You have to use File.read to read the html opened by open-uri.

require 'nokogiri'
require 'open-uri'
require 'net/http'

doc = Nokogiri::HTML(File.read(open('http://shareinvestor.com').path))
puts doc.text # this one now returns the correct html

I attended the Red Dot Ruby Conference this year at NUS University Cultural Centre last Friday and Saturday. It was a two days event and attracted approximately 200 programmers around the world.

Llya Grigorik from google gave a very interesting talk on how to build a faster web using various technics. If you are experiencing slow website problem, you may want to check out his slides at Building a Faster Web.

There are also a lot of interesting topics that were discussed during the conference e.g PUBSUB infrastructure, Client Slide Templating, Using Redis to improve site performance, CoffeeScript etc.

Red Dot Ruby Conference 2012

Red Dot Ruby Conference 2012

I love Rails Console. If there is anything wrong with my Rails application, I can simply fire the console, and debug from there. Rails makes the query to db very simple and elegant by providing us the ActiveRecord. However, sometimes you may want to know the underlying raw sql statement being sent to the database to see if there is any problem. Especially your rails app is being quite slow, you may want to check if this could be the problem.


So you know that under development mode, the log would print out the raw sql statements executed. What about Rails Console. By default, if you typed in any code that queries the database, it would simply return the objects back to you. You can do the following in order to show the raw sql statements:


Immediately after you have entered Rails Console, typed in the following code in console:


ActiveRecord::Base.logger = Logger.new(STDOUT)

After that, it should print out the sql queries.

If you want to parse a string into Time object, normally you would do the following

Time.parse('2011-12-31 08:56')
Time.parse('12/31/2011 08:56')

However, this parse method require the string to be in this specific format. If you try to run the following code:

Time.parse('31/12/2011 08:56')

You will get ArgumentError: argument out of range error. To parse string into Time with custom format, you can do this

require 'date'
def string_to_time time_, format_
 time = Date._strptime(time_, format_)
 return Time.local(time[:year], time[:mon], time[:mday], time[:hour], time[:min], time[:sec], time[:sec_fraction], time[:zone])
end

With the above function, you can call the parsing of time in this way:

string_to_time('31/12/2011 08:56', '%d/%m/%Y %H:%M')