Class method declarations help

E

Eckie Silapaswang

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?

Best regards,

Eckie
 
C

Chris Carter

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?

Best regards,

Eckie
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
 
J

jmb-d

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

Thanks, in advance,
jmb-d
 
M

MenTaLguY

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

This has come to be my own preference as well, due to the POLT (Principle of Least Typing) :)

-mental
 
P

Phrogz

The lines of particular interest to me are the

def self.create_from_hash(hash)

and the

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
 
P

Phrogz

This has come to be my own preference as well, due to the POLT (Principle of Least Typing) :)

Although I see your smiley, let's analyze this.

irb(main):001:0> "class << self".length
=> 13
irb(main):002:0> "end".length
=> 3
irb(main):003:0> "self.".length
=> 5
irb(main):004:0> 16 / 5
=> 3

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

Robert Dober

The lines of particular interest to me are the

def self.create_from_hash(hash)

and the

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top