Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Defining class methods

Reply
Thread Tools

Defining class methods

 
 
Tony Arcieri
Guest
Posts: n/a
 
      02-16-2011
[Note: parts of this message were removed to make it a legal post.]

It seems there are 3 ways of defining class methods (at least in common
usage):

1) Defining a method on self:

def self.method

2) Opening up self and defining the methods directly:

class << self
def method
...
end

3) Placing class methods into a module, and extending a class with that:

module ClassMethods
def method
...
end

extend ClassMethods

--

Which of these do you use and which do you prefer? Do you use all three? Do
you think class << self is fugly and confusing?

I used to use class << self quite frequently and have been shifting to using
modules when dealing with a large number of class methods. I can't really
say I'm a huge fan.

--
Tony Arcieri
Medioh! Kudelski

 
Reply With Quote
 
 
 
 
Anurag Priyam
Guest
Posts: n/a
 
      02-16-2011
On Thu, Feb 17, 2011 at 1:17 AM, Tony Arcieri <> wro=
te:
> It seems there are 3 ways of defining class methods (at least in common
> usage):
>
> 1) Defining a method on self:
>
> def self.method
>
> 2) Opening up self and defining the methods directly:
>
> class << self
> =A0def method
> =A0...
> end
>
> 3) Placing class methods into a module, and extending a class with that:
>
> module ClassMethods
> =A0def method
> =A0...
> end
>
> extend ClassMethods
>
> --
>
> Which of these do you use and which do you prefer? Do you use all three? =

Do
> you think class << self is fugly and confusing?


I use all three, depending on the situation. Generally, I use method 2
(class << self), but if I have an idea that I will be needing only
one, or two class methods (like Module.included) I use method 1 (def
self.foo). If it makes sense to separate the class methods from the
core definition of a class (like helper/utility functions), I define
them in a module in a separate file.

I do not find class << self to be ugly and confusing .

I picked up the following pattern going through DataMapper's code (or,
was it Ruby Best Practices?).

module Foo
def instance_method; puts "im"; end

module ClassMethods
def class_method1; puts "cm" end
end

def self.included(klass)
klass.extend(ClassMethods)
end
end

class Moo
include Foo
end

Foo.class_method #=3D> cm
Foo.new.instance_method #=3D> im
Foo.new.class_method #=3D> NoMethodError

A use case of this pattern for me was defining a Helper module for
Sinatra (modular) app where some helpers will be used in the
request-response context, while some in the context of the class that
inherits from Sinatra::Base.

--=20
Anurag Priyam
http://about.me/yeban/

 
Reply With Quote
 
 
 
 
Avdi Grimm
Guest
Posts: n/a
 
      02-17-2011
On Wed, Feb 16, 2011 at 4:37 PM, Anurag Priyam <> wrote:
>> 1) Defining a method on self:
>>
>> def self.method


This one. That way you can always tell simply by looking at the method
definition that it is a class/module-level method.

 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      02-17-2011
On Thu, Feb 17, 2011 at 3:47 AM, Tony Arcieri <> wrote:
> It seems there are 3 ways of defining class methods (at least in common
> usage):
>
> 1) Defining a method on self:
> 2) Opening up self and defining the methods directly:
> 3) Placing class methods into a module, and extending a class with that:


4) Explicit definition

def C.m
...
end

i usually use this one since
1 it's visibly specified. The definition matches the use.
2 don't need to press pgup just to see who is self
3 if i change class name, it self checks itself since i need to retype.
4 less prone to self abuse

best regards -botp


best regards -botp

 
Reply With Quote
 
Avdi Grimm
Guest
Posts: n/a
 
      02-17-2011
On Wed, Feb 16, 2011 at 9:55 PM, botp <> wrote:
> 4) Explicit definition
>
> def C.m
> ...
> end


I avoid this one because it makes class renames more of a chore.

--
Avdi Grimm

 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      02-17-2011
On Thu, Feb 17, 2011 at 11:14 AM, Avdi Grimm <> wrote:
> I avoid this one because it makes class renames more of a chore.


Indeed. and that's what i like i about it. makes me think more on the
value of naming

best regards -botp

 
Reply With Quote
 
John Feminella
Guest
Posts: n/a
 
      02-17-2011
> It seems there are 3 ways of defining class methods (at least in common
> usage):


There's lots of ways to add a class method; Ruby is not a very
prescriptive language. Two more interesting examples that are used:
there's `instance_eval` on a Class instance:

X = Class.new
X.instance_eval do
def foo; "calling #foo!"; end
end

X.foo
# => "calling #foo!"

or #class_eval on the class of your `Class` instance (which will be `Class`):

X.class.class_eval do
def bar; "calling #bar!"; end
end

X.bar
# => "calling #bar!"

It's not very complicated, but `class_eval` on a Class instance is
typically used only in some rather advanced (and/or cryptic)
metaprogramming, so you don't see it floating around a lot.

~ jf
--
John Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: http://stackoverflow.com/users/75170/



On Wed, Feb 16, 2011 at 21:55, botp <> wrote:
> On Thu, Feb 17, 2011 at 3:47 AM, Tony Arcieri <> wrote:
>> It seems there are 3 ways of defining class methods (at least in common
>> usage):
>>
>> 1) Defining a method on self:
>> 2) Opening up self and defining the methods directly:
>> 3) Placing class methods into a module, and extending a class with that:

>
> 4) Explicit definition
>
> def C.m
> ...
> end
>
> i usually use this one since
> 1 it's visibly specified. The definition matches the use.
> 2 don't need to press pgup just to see who is self
> 3 if i change class name, it self checks itself since i need to retype.
> 4 less prone to self abuse
>
> best regards -botp
>
>
> best regards -botp
>
>


 
Reply With Quote
 
Shadowfirebird
Guest
Posts: n/a
 
      02-17-2011
I don't mean it as a put-down; I suspect the only person I'm putting down is myself. But I don't find that class methods actually come up much in my Ruby coding; when I find myself coding one I tend to stop and think hard about whether I actually need it.

And when I do use one it's always your type (1). Why would I want to define a class method anywhere else but in the class? I do understand that for DSLs, all the rest of this syntax is really useful. But -- showing my ignorance here -- is it really of any practical value elsewhere?

--
A boss with no humor is like a job that's no fun.

 
Reply With Quote
 
Avdi Grimm
Guest
Posts: n/a
 
      02-17-2011
On Thu, Feb 17, 2011 at 4:41 AM, Shadowfirebird
<> wrote:
> I don't mean it as a put-down; I suspect the only person I'm putting down=

is myself. =A0 But I don't find that class methods actually come up much i=
n my Ruby coding; when I find myself coding one I tend to stop and think ha=
rd about whether I actually need it.

Indeed. Class methods in Ruby are a code smell: not always wrong, but
you should always think about why you're choosing a class-level method
instead of instance-level.

I think most of the class/module-level methods I write are "macros" -
e.g. methods along the lines of Ruby's #attr_accessor.

--=20
Avdi Grimm
http://avdi.org

 
Reply With Quote
 
John Feminella
Guest
Posts: n/a
 
      02-17-2011
> Indeed. Class methods in Ruby are a code smell: not always wrong, but
> you should always think about why you're choosing a class-level method
> instead of instance-level.


I don't know if I'd go so far as to say they're a code smell. Without
class methods a number of very useful Ruby DSLs wouldn't exist in
their current form (RSpec, Cucumber, Rails, etc., just to name a few).
I agree that they can be abused or misused, but that's true of pretty
much any construct in any language, isn't it?

I'd probably arrange my skepticism of a class method from lowest to
highest in this way, depending on its features:

* part of a DSL (`describe`, `Before`, `callback { ... }`, etc.)
* repository pattern (Widget.find(...))
* factory pattern (Widget.orange # =3D> <orange Widget instance>)
* method takes more than a parameter or two
* non-factory class method with variable args
* instance of the class method's class is in the arguments/params
list (often very questionable)

~ jf
--
John Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: http://stackoverflow.com/users/75170/



On Thu, Feb 17, 2011 at 10:03, Avdi Grimm <> wrote:
> On Thu, Feb 17, 2011 at 4:41 AM, Shadowfirebird
> <> wrote:
>> I don't mean it as a put-down; I suspect the only person I'm putting dow=

n is myself. =C2=A0 But I don't find that class methods actually come up mu=
ch in my Ruby coding; when I find myself coding one I tend to stop and thin=
k hard about whether I actually need it.
>
> Indeed. Class methods in Ruby are a code smell: not always wrong, but
> you should always think about why you're choosing a class-level method
> instead of instance-level.
>
> I think most of the class/module-level methods I write are "macros" -
> e.g. methods along the lines of Ruby's #attr_accessor.
>
> --
> Avdi Grimm
> http://avdi.org
>
>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
Defining class methods outside of classes Lord Landon Python 1 05-04-2006 06:07 AM
defining or not defining destructors johny smith C++ 8 07-02-2004 08:51 AM
Defining *class* methods on C code Thomas Heller Python 12 02-09-2004 11:37 AM
Modules defining class methods to include? Tim Bates Ruby 3 02-03-2004 04:05 AM



Advertisments