Archives: October 2007

Beware of raising exceptions

I was reading on twitter experience of scaling rails and use of dtrace. Unfortunately for GNU/Linux users “dtrace” is just a unreality. But if you just concentrate on the results, then you will find that, a major source of bottleneck was use of:

  foo = @someobj.amazing rescue "not_amazing"

Above code is in vogue, because it takes care of a lot of things like:

  • if @someobj is nil, then foo defaults to “not_amazing”.
  • if @someobj doesn’t support “amazing” method, foo defaults to “not_amazing”.
  • And of course the obvious case.

But that code succinctness comes at a cost and you may end up with deep stacktraces. This was a major bottleneck for twitter team.
Above snippet can be written as:

foo = @someobject.blank? ? "not_amazing" : (@someobject.respont_do?(:amazing) ? @someobject.amazing : "amazing")

Not so succinct, but does its job.

Read the details http://blogs.sun.com/ahl/entry/dtrace_for_ruby_at_oscon .

Useful discoveries of the day

This post is more of a “tumbler” style, but since I am lazy and doesn’t want to elaborate more and rather I would let respective links speak for themselves.

1. When you are working to create some sort of platform from scratch, you may find that your database is kinda stopping you from going full speed ahead. You may have several backend components and each of them interact with your database. But the problem with databases are, only so few connections it can spare and it becomes a bottlebeck afterwards. Geeks at newyork times( thats right, the newspaper guys) have developed a little utility called dbslayer, which lets you perform sql queries on database using JSON and it returns JSON responses. This is pretty neat and since it does this over HTTP, your database can scale. So, the idea is basically to use dbslayer layer in applications that are not too much into database and don’t basically need a persistence connections. Here is the link: http://code.nytimes.com/projects/dbslayer . And here is a little Ruby code sample, on how to perform a sql query using dbslayer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require "rubygems"
require 'open-uri'
require "json"
 
@slayer_server = "localhost"
@slayer_port = "9090"
 
def query_url(sql)
  query_hash = { "SQL" => sql }
  url_args = URI.encode(query_hash.to_json)
  "http://#{@slayer_server}:#{@slayer_port}/db?#{url_args}"
end
 
def exec_query(sql)
  url = query_url(sql)
  open(url) do |f|
    yield JSON.parse(f.read)
  end
end
 
exec_query("select login from users") do |results|
  p results
end

2. In Ruby 1.9, matz has checked in support for Fluent Interfaces . Its pretty neat. David Flanganan talks about it here . David is the guy, who wrote “Javascript: the Definitive guide”. Good to see him working on Ruby.

3. Its hard to predict schedule of a software project because of so many uncertain things involved. Fred Brooks, Mythical man month is a milestone work on it. But looks like Joel’s team has done wonders in solving this uncertainty. Here Joel talks, how you can use Evidence bases scheduling for scheduling your project with reasonable accuracy. On a related note, here Joel talks, how having a active bug database is essential for a software project.

4. On edge rails, now you can refer fixtures as if they had associations. Its quite nice and makes job a lot easier for guys, who relied on fixtures for testing. There are certain cases against fixtures and how they make your tests “brittle”. But I have come to realize that, a combination of fixtures and mocks are probably best way to go. Here Pratik talks about latest code changes.

5. “A little Ruby” is a nice book for experienced Ruby developers who are looking to learn metaprogramming with Ruby. The sad part is, its not complete. Now, with growing interest in Ruby, the author wonders whether he should revive the project and complete the book. Vote for completion here

Using ‘?’ for wierdness

? is Ruby shorthand for referencing a character.

   irb(main):020:0> ?a => 97 
   irb(main):021:0> ?a == "a"[0] => true
   irb(main):014:0> ?? => 63 
   irb(main):015:0> !?? => false 
   irb(main):016:0> !!?? => true

Since ?? equals 63, it is equivalent to true in a boolean test. That means we can negate it with a bang!

Using class instance variables in ruby

We all know how evil class variables are, and they are as dangerous as the “three headed dog” at the dungeon and we shall not talk about it.
But they are necessary for many of the thingies ruby does and used extensively.But today we shall not talk about them.
We saw earlier that, although class instance variables are excellent, but not so friendly to use and they make Ruby look like C++(ahem).

Here goes a little hack, that allows you to define class level attributes based on class instance variables. Since, i often use it in rails and they have taken cattr for class level attributes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Object
  def self.metaclass; class << self; self; end; end
 
  def self.iattr_accessor *args
 
    metaclass.instance_eval do
      attr_accessor *args
      args.each do |attr|
        define_method("set_#{attr}") do |b_value|
          self.send("#{attr}=",b_value)
        end
      end
    end
 
    args.each do |attr|
      class_eval do
        define_method(attr) do
          self.class.send(attr)
        end
        define_method("#{attr}=") do |b_value|
          self.class.send("#{attr}=",b_value)
        end
      end
    end
  end
end

Now you can easily write code like this:

1
2
3
4
5
6
class Foobar
  iattr_accessor :hello
end
 
Foobar.hello = "I am a class instance atrribute"
p Foobar.hello