December 22, 2005

Ruby's executable class definitions

If you're coming to Ruby from Java, remember that class definitions are executable code. I can think of at least one situation where this has practical implications and if you're not clear about it you'll spend a couple of hours banging your head against the wall.

Consider this simple Java class:

class A
{
  int a = 10;

  public int getA()
  {
    return a;
  }
}


If you create an object of type A and call it's method getA(), you'll get 10. No surprises here.

Now, knowing that member variables in Ruby are prefixed with @ we go ahead and translate our little java class to Ruby like so:


class A
  @a = 10

  def a
    return @a
  end
end


We then create an object of class A and call its a() method:

irb(main):001:0> class A
irb(main):002:1> @a = 10
irb(main):003:1> def a
irb(main):004:2> return @a
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> A.new.a
=> nil


"WTF!!" you say. Well, if you remembered what I said, class definitions are executable code. In our case, this means that the @a = 10 is executed when the class is defined, not when an instance of the class is created. As a result, this statement defines a member variable of the instance of class Class that represents class A.

To prove the last statment is true, let's make a() a class method:

class A
  @a = 10

  def A.b
    return @a
  end
end


When we call it we get what we expected:

irb(main):001:0> class A
irb(main):002:1> @a = 10
irb(main):003:1> def A.a
irb(main):004:2> return @a
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> A.a
=> 10

Labels:

0 Comments:

Post a Comment

<< Home