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?
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?
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.
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.
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.
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.