Defining class methods

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

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 #=> cm
Foo.new.instance_method #=> im
Foo.new.class_method #=> 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.

···

On Thu, Feb 17, 2011 at 1:17 AM, Tony Arcieri <tony.arcieri@medioh.com> wrote:

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?

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

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 :slight_smile:
3 if i change class name, it self checks itself since i need to retype.
4 less prone to self abuse :slight_smile:

best regards -botp

best regards -botp

···

On Thu, Feb 17, 2011 at 3:47 AM, Tony Arcieri <tony.arcieri@medioh.com> 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:

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.

It depends on whether and how you want to allow methods to be
overridden. Using #extend and 'def self.xxx' are not the same, viz:

    module A
      def run
        puts "A"
      end
    end

    class Foo
      extend A
    end

    class Bar
      extend A
    end

    Foo.run # => "A"
    Bar.run # => "A"

    module B
      def run
        puts "B"
      end
    end

    class Foo
      def self.run
        puts "foo"
      end
    end

    Foo.extend(B)
    Bar.extend(B)

    Foo.run # => "foo" - extend does not
override a def self.method
    Bar.run # => "B" - but it does override a
previously defined extension

    class Foo
      class << self
        def run
          puts "bar"
        end
      end
    end

    Foo.run # => "bar" - using 'class << self;
def method' ... same as 'def self.method'

Personally, I've come to prefer using #extend.

Regards,
Sean

···

On Wed, Feb 16, 2011 at 7:47 PM, Tony Arcieri <tony.arcieri@medioh.com> wrote:

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

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

···

On Wed, Feb 16, 2011 at 4:37 PM, Anurag Priyam <anurag08priyam@gmail.com> wrote:

1) Defining a method on self:

def self.method

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

···

On Wed, Feb 16, 2011 at 9:55 PM, botp <botpena@gmail.com> wrote:

4) Explicit definition

def C.m
...
end

--
Avdi Grimm

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: User John Feminella - Stack Overflow

On Wed, Feb 16, 2011 at 21:55, botp <botpena@gmail.com> wrote:

On Thu, Feb 17, 2011 at 3:47 AM, Tony Arcieri <tony.arcieri@medioh.com> 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 :slight_smile:
3 if i change class name, it self checks itself since i need to retype.
4 less prone to self abuse :slight_smile:

best regards -botp

best regards -botp

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.

···

On Thu, Feb 17, 2011 at 4:41 AM, Shadowfirebird <shadowfirebird@gmail.com> wrote:

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.

--
Avdi Grimm

Well, more specific than DSLs: metaprogramming, and DSLs that generate code.

Some of the more abject design patterns, such as the factory pattern, can
often be avoid thanks to a combination of Ruby's dynamism and class methods.

The class is also a great place to stick state shared by all instances of
that class, such as the configuration details for accessing a particular
network service.

···

On Thu, Feb 17, 2011 at 2:41 AM, Shadowfirebird <shadowfirebird@gmail.com>wrote:

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?

--
Tony Arcieri
Medioh! Kudelski

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

best regards -botp

···

On Thu, Feb 17, 2011 at 11:14 AM, Avdi Grimm <groups@inbox.avdi.org> wrote:

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

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 # => <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: User John Feminella - Stack Overflow

On Thu, Feb 17, 2011 at 10:03, Avdi Grimm <groups@inbox.avdi.org> wrote:

On Thu, Feb 17, 2011 at 4:41 AM, Shadowfirebird > <shadowfirebird@gmail.com> wrote:

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.

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