Hope everyone is having a great weekend! I was looking over some code
concerning class method declarations as shown below:
#2
class Animal
attr_accessor :species, :form
def self.create_from_hash(hash)
a = new
a.species = hash[:species]
a.form = hash[:form]
a
end
end
Animal::create_from_hash(:species => :fox, :form => :cartoon) # =>
#3
class Animal
attr_accessor :species, :form
class <<self
def create_from_hash(hash)
a = Animal.new
a.species = hash[:species]
a.form = hash[:form]
a
end
end
end
Animal::create_from_hash(:species => :fox, :form => :cartoon) # =>
The lines of particular interest to me are the
def self.create_from_hash(hash)
and the
class << self
def create_from_hash(hash)
I remember reading from the “Ruby for Rails” book that there’s a “subtle
difference between these two approaches to defining a singleton method,
involving the scope of constants, but that’s an arcane point. For the
most part, you can treat them as equivalent”.
My questions to all the Rubyists out there is, do you have a particular
preference between the two choices? Is this a style issue? Or is there
really a concrete “it depends on this” factor?
Hi Eckie,
Generally speaking, if you only have 1 or 2 class methods you use the
self.method syntax, and if you have a lot of class methods you use the
class<<self syntax
Generally speaking, if you only have 1 or 2 class methods you use the
self.method syntax, and if you have a lot of class methods you use the
class<<self syntax
OK, Chris – I’ll bite: why the preference for 1 or 2 class methods
using “def self.my_method_name” over having many using the “class <<
self…”?
class << self
def create_from_hash(hash)
[snip]
My questions to all the Rubyists out there is, do you have a particular
preference between the two choices? Is this a style issue? Or is there
really a concrete “it depends on this” factor?
I personally prefer the former, as I think any sane person would.
Imagine that you’re scrolling through some code and see:
def foo( bar )
and I ask you “Quick! Is that a ‘class’ method or an instance method?”
If you only use the former style, you know immediately that it’s an
instance method. If you use the latter style, you need to scan up to
the top of the class, looking at every line and possibly indentation
to see if maybe you’re inside the singleton class or not.
The only time I use class << self in a class definition is for the
simple, few-line:
class << self
attr_accessor :foo, :bar
end
You’d need to type four or more ‘class’ methods before you made up for
the overhead of typing that the singleton class technique requires.
Though I suppose you could go crazy terse and use “class<<self”,
saving two spaces and bringing the breakeven point down to three or
more class methods.
But as I pointed out in my other reply, having many methods in the
singleton is exactly the time when (IMO) you don’t want to get
orphaned from the singleton opening. It’s too easy to mistake a class
method for an instance (and vice-versa).
The good news, though, is that RDoc correctly documents both styles as
class methods.
My questions to all the Rubyists out there is, do you have a particular
the top of the class, looking at every line and possibly indentation
to see if maybe you’re inside the singleton class or not.
The only time I use class << self in a class definition is for the
simple, few-line:
class << self
attr_accessor :foo, :bar
end
Mainstream, mainstream, …
I think there is some semantic information conveyed, which of course
is very personal.
When I write
class C
<methods & friends>
class << self
end
end
this marks a unit
class C
<methods & friends>
end
class << C
end
that is somehow strange though I use it a lot because the code seems
more readable but it marks a seperation, I just recently tried to
understand Facet’s philosophy of spreding classes and modules all over
the place, sometimes this gives great flexibility when coming to
maintenance
per consequence on could write the two blocks into two different files
Sometimes I use classes or modules only as namespaces than I want to
show off that I am not sane (which is a virtue of course
class << C = Class.new( WhateverSuperClass )
end
or
class << M = Module.new
end
instead of
C Class.new…
class << C
actually there are minor inconveniences for each notation.
Robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.