72

This Ruby Style Guide tells that is better using self.method_name instead of class method_name. But Why?

class TestClass
  # bad
  class << self
    def first_method
      # body omitted
    end

    def second_method_etc
      # body omitted
    end
  end

  # good
  def self.first_method
    # body omitted
  end

  def self.second_method_etc
    # body omitted
  end
end

Are there performance issues?

Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
Mich Dart
  • 2,352
  • 5
  • 26
  • 44
  • 23
    It's hard to take a style suggestion seriously if there's no accompanying explanation, isn't it? – Michael Berkowski Jun 09 '12 at 19:51
  • 3
    Note that it says "_This is a guide we use for our own ruby apps internally at GitHub._" That is, this is the style Github has defined for its own use. It isn't a definitive guide to correct Ruby style. – Michael Berkowski Jun 09 '12 at 19:53
  • 1
    I agree, but seems to be written from well-formed Rubyists with authority skills. – Mich Dart Jun 09 '12 at 19:53
  • This other guide gives a more suitable point of view: https://github.com/bbatsov/ruby-style-guide Search for "class << self" inside the page. ;) – Mich Dart Jun 09 '12 at 19:57
  • 1
    For *me*, `self` is more readable. Plus, it's a kind of standard (I've never seen a gem/app/etc. using `class <<`). – Samy Dindane Jun 09 '12 at 19:57
  • I find self.xxx more communicative, and IIRC there *is* a technical difference, but I don't recall what it is. It also came up in another question I answered where a technique worked with self.xxx but not class <<. – Dave Newton Jun 09 '12 at 20:01
  • possible duplicate of [Difference between 'self.method_name' and 'class << self' in Ruby](http://stackoverflow.com/questions/2025569/difference-between-self-method-name-and-class-self-in-ruby) – knut Jun 09 '12 at 20:10
  • 3
    This is me being picky, but please don't use `class << self`, don't say metaclass, and especially don't say Eigenclass. Those are all confusing, outdated names for something that Ruby actually has a proper name for: the singleton class. Instead of `class << self` use `singleton_class.class_eval` which is much more clear about what's going on. Or for single methods use `define_singleton_method` which is even more explicit. – Max Jun 09 '12 at 20:26
  • self.method_name is easier to read and you don't have to rename the method if you change the class name if you use class_name.method_name. Overall, it's more conducive to refactoring. Use class << self only if the implementation requires metaprogramming – fontno Sep 08 '13 at 22:12
  • @Max `singleton_class` just made my day. Thank you. The project I'm working on always reopens using `class_eval` and the like, in order to catch naming errors as early as possible. – Keen Jun 18 '14 at 02:12

6 Answers6

103

class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method form then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.

def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.

Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.

Gareth
  • 133,157
  • 36
  • 148
  • 157
  • 8
    I disagree, this is not just a simple personal choice. There is a code readability downside to using `<<` -- see @Flexoid's answer. The downside to the `class << self` syntax and using a code block, is that if the block is longer than a few methods, it is not apparent that these methods are class methods, unless you scroll up to the `class << self` section. – Dmitri Zagidulin Jan 17 '14 at 03:12
  • 2
    That's not a problem specific to `class << self` though. I've seen plenty of source files (more often in large, nontrivial projects) with deep module nesting, where it isn't clear until you scroll up which *class* a method is in – Gareth Jan 17 '14 at 08:24
  • 1
    @DmitriZagidulin In that case you can tell these methods are class methods based on indention. – weakish Apr 29 '15 at 01:00
  • 1
    "then there's no guarantee (other than convention and wishful thinking)" <-- @Gareth But there is no still guarantee that there will not be additional `self.method` declaration along side `self << class`. "Do not mix up these two styles" is a convention. – weakish Apr 29 '15 at 01:06
  • 1
    @DmitriZagidulin Don't want to sound rude, but this argument is ridiculous. It would apply to anything, i.e.: "The downside of using `protected` methods is that if you define more than a few methods, it is not apparent that these methods are protected, unless you scroll up to `protected` section". – Andre Figueiredo Mar 28 '19 at 14:14
32

Generally, class << self is used in metaprogramming to set the class as self for a prolonged period of time. If I'm trying to write 10 methods, I would use it like so:

METHOD_APPENDICES = [1...10]
class << self
  METHOD_APPENDICES.each do |n|
    define_method("method#{n}") { n }
  end
end

This would create 10 methods (method1, method2, method3, etc.) that would just return the number. I would use class << self for clarity in this case because in metaprogramming self is crucial. Littering self. inside there would actually make things less readable.

If you're just defining class methods normally, stick to self.class_method_name because more people are likely to understand it. No need to bring in meta-syntax unless you expect your audience to understand it.

Chris
  • 11,819
  • 19
  • 91
  • 145
  • Imho, the best answer. However, it gives a non-subjective reason on that ruby have 2 syntax styles to define class method. – 18augst Sep 13 '14 at 20:33
30

As noted above, both styles seem to be equivalent, however using class << self allows one to mark class methods as private or protected. For example:

class UsingDefSelf
  def self.a; 'public class method'; end
  private
  def self.b; 'public class method!'; end
end

class UsingSingletonClass
  class << self
    def a; 'public class method'; end
    private
    def b; 'private class method'; end
  end
end

private only affects instance methods. Using the singleton class, we are defining instance methods of that class, which turn into class methods of the containing class!

We can also mark class methods as private with def self:

class UsingDefSelf
  def self.a; 'private class method'; end
  def self.b; 'private class method!'; end
  private_class_method :a, :b
  # In Ruby 2.1 there is an alternative syntax
  private_class_method def self.c; 'private class method!'; end
end

But we cannot mark them as protected, there is no protected_class_method. (However, since class is the only instance of its singletonclass, private class method and protected class methods are almost the same except their calling syntax is different.)

Also it is less easier than using class << self to mark private class methods, since you have to list all method names in private_class_method or prefix private_class_method to every private class method definition.

weakish
  • 28,682
  • 5
  • 48
  • 60
7

Whichever you want. Both are very clear for what you do. But I think of some recommendations for this.

When there're only one class method to define, Use def self.xxx. Because for defining only one method, increasing indent level probably become cluttering.

When there're more than one class method to define, Use class << self. Because writing def self.xxx, def self.yyy and def self.zzz is certainly repetition. Create a section for these methods.

When all methods in a class are class method, you can use module with module_function instead of class. This let you define module functions just use def xxx.

weakish
  • 28,682
  • 5
  • 48
  • 60
nonowarn
  • 620
  • 8
  • 18
6

I assume that they think self.* is better because you can say for sure, it's a class or instance method, without having to scroll up and seaching this class << self string.

Flexoid
  • 4,155
  • 21
  • 20
  • 1
    I'm surprised by the other answers to this question; this is the only sane way to do it. If you write `class << self` it's only apparent to the reader that the methods are class methods if a) you've only got a small number of them, *AND* b) the `class << self` line is currently visible in your editor. It's also easy to grep for class and instance methods if you follow the `def self.thing` convention. Dave Thomas suggests `<< self` be reserved for when you need to change `self` (within the block; e.g. to call attr_accessor on the class). – Graham Ashton Sep 10 '13 at 13:11
  • 4
    But at that point, would it be just as "unreadable" to have private methods? since they are all indented under the "private" keyword. I suppose in ruby you can explicitly call "private :method" for every method, but given how C syntax works, I feel it's not unreasonable to expect developers to know that function/method definitions might have context around it. – Alexander Bird Feb 04 '14 at 21:21
-3

So far the question and answers only discuss these two options:

class MyClass
  def self.method_name
    ..
  end
end

class MyClass
  class << self
    def method_name
      ..
    end
  end
end

There's a third option to consider for class methods:

class MyClass
  def MyClass.method_name
    ..
  end
end

It's not popular and is more verbose, but it's the most explicit option.

It's also less confusing if you mix up self behaviour between Python and Ruby.

Dennis
  • 56,821
  • 26
  • 143
  • 139
  • "I also come from a Python background where self is used for instance methods, whereas in Ruby, self is used for class methods. This often confuses me" <-- This is because in Ruby "class" is an "instance". And in Python instance method is `def m(self, args):`, and Ruby is def(args)(just omit "self" and ":"). – weakish Apr 29 '15 at 01:29
  • 2
    Please don't use this style, ruby is a language with highly opinionated community. This allows devs to code side by side without explaining too much or on things. This just sets your own unique standards. – Adit Saxena Nov 30 '15 at 10:04
  • @AditSaxena having a styleguide for your project/team solves that. (FWIW, I no longer use the option I proposed since I program almost exclusively in Ruby now and have gotten used to `self`, but it's still good to know about the different options.) – Dennis Nov 30 '15 at 10:16