views:

124

answers:

4

Given the following two ways of defining a class method in Ruby:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

Is there a difference between the two? Is one more preferable than the other?

+3  A: 

In short: no and no.

It comes down to personal preference. The first version saves you typing if you define many class methods. The second one may be preferable if you dislike the obscurer syntax of the first.

molf
I guess the 15 character limit is to stop people like me just typing 'lol'
Chalkey
Thanks, that's what I'd figured. :)
Daniel Vandersluis
A: 

As molf said, there's no effective difference. But IMO, the second is so much more skimmable -- it's too easy to miss the class<<self and think you're still looking at instance methods. I only tend to use the class<<self route when I need more dynamic behavior, such as making attr_accessor properties of the class itself.

Chuck
A: 

Option 1. will get you into trouble if you've got a lots of lines of code between class << self and the corresponding end. If you don't notic that a method has been defined inside the class << self block, you might think its just an instance method.

Option 2. is more typing, more expressive and more understandable to the untrained Ruby-eye.

Theyre's no difference in the end-result as others have pointed already.

Ijonas
+3  A: 

Just to clarify the terminology: there is no such thing as a "class method" in Ruby. What you are doing is to define a singleton method on the object that is the class Foo (remember, classes are objects, too, just like any other). In turn, singleton methods don't really exist, either, they are just normal instance methods on the eigenclass (commonly referred to as Foo′) of the object, which in this case is also the metaclass of the class Foo.

Confused yet? :-)

Basically, there is no difference between doing this:

foo = Object.new
class << foo
  def bar
    # ...
  end
end

def foo.baz
  # ...
end

and this:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

Because inside a class definition, self is bound to the class object (in this case Foo), that is equivalent to:

class Foo
  class << Foo
    def bar
      # ...
    end
  end

  def Foo.baz
    # ...
  end
end

Which is in turn equivalent to:

Foo = Class.new
class << Foo
  def bar
    # ...
  end
end

def Foo.baz
  # ...
end

Which as you can see is pretty much exactly the same as my first example. This shows that there really is no difference between a singleton method on a class method and a singleton method on any other kind of object, therefore it doesn't make sense to talk about "class methods" in Ruby.

You can also see how these two notations relate to the notion of singleton methods and eigenclasses:

def foo.baz
  # ...
end

says "add the singleton method baz to the object foo" and

class << foo
  def bar
    # ...
  end
end

"open up the eigenclass of object foo and then add instance method bar to the eigenclass". But, as we established earlier, a singleton method of the object and an instance method of the object's eigenclass are really the same thing. That's why it wouldn't make sense for those two notations to behave differently.

Jörg W Mittag
It doesn't make sense to discourage the term "class methods": the name does not conflict with anything. These methods are indeed just instance methods on metaclasses. But they are quite commonly referred to as class methods in Ruby, including nearly all (core) Ruby documentation. In daily use they are identical to class methods (static methods) in other languages.
molf