6

What are the differences between

module Logging
  def self.log
    if @logger.nil?
      @logger = Logger.new STDOUT
    end
    @logger
  end
end

and this?

class Logging
  def self.log
    if @logger.nil?
      @logger = Logger.new STDOUT
    end
    @logger
  end
end

They both appear to do the same thing. Why would I choose one over the other?

Spencer Wood
  • 610
  • 6
  • 15
  • 1
    Possible duplicate of http://stackoverflow.com/questions/151505/difference-between-a-class-and-a-module – Chaitanya Kale Jul 16 '16 at 04:01
  • 1
    Would not consider this a duplicate. The question is asking to clarify the difference between class methods and module methods, not classes and modules. – Ceasar May 18 '18 at 22:16

4 Answers4

8

tl;dr: There are no class methods and module methods in Ruby, only instance methods. Considering that they are both just instance methods, and thus the same thing, there cannot possibly be any difference.


There is no such thing as a "class method" or a "module method" in Ruby. Ruby has exactly one kind of method: instance methods.

We sometimes use the word "class method" or "module method" out of convenience when talking about a certain pattern of using instance methods, but there is no such concept in Ruby. "Class methods" and "module methods" are really just singleton methods of an object which just happens to be an instance of the Module class or the Class class. There is absolutely no difference whatsoever between a singleton method of an object which happens to be an instance of Class, Module, String, Array, Hash, Object, Foo, Bar, Whatever, or Garbledigookidoo.

Oh. Did I mention? Singleton methods don't exist, either. Again, it is a word we use for certain kinds of usages of methods, but they are really just regular boring old instance methods of the singleton class of an object.

However, "instance method of the singleton class of foo" and "instance method of the singleton class of Foo, where Foo is an instance of Class" are really long, and so we shorten them to "singleton method of foo" and "class method of Foo" out of convenience, knowing full well that those are fictions that don't actually exist in the language.

Unlike Java, which has three different kinds of methods (instance methods, static methods, and constructors (which are kinda-sorta like methods)), Ruby has exactly one kind of method: instance methods. No class methods, no module methods, no global methods, no top-level methods, no static methods, no constructors. It does, however, have three kinds of classes: regular classes, singleton classes, and include classes (the latter being classes that get synthesized and injected into the inheritance hierarchy when you call include or prepend). These classes differ mainly in whether methods like Object#class, Class#superclass, and Class#ancestors display them or suppress them. Singleton classes are suppressed by all of them, include classes by the first two, but shown by ancestors.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Can you explain what a class method then if it does not exist? If I invoke `Math.abs` is that invoking the instance method `abs` on an instance of `Math`? – Ceasar May 18 '18 at 22:13
  • No, it is invoking the instance method `abs` defined in the singleton class of `Math` on the object `Math`. I can't explain what a class method is, since it doesn't exist. What we Rubyists sometimes call a "class method" is simply a singleton method of an object that happens to be an instance of the `Class` class. But singleton methods don't exist as a language construct either. They are just instance methods of the singleton class. We just call them that as a shorthand. – Jörg W Mittag May 19 '18 at 00:37
  • This answer and https://ruby-doc.com/docs/ProgrammingRuby/html/tut_modules.html helped me. – user664833 Jun 11 '19 at 22:47
4

Jörg Mittag is correct that there technically are no class methods or module methods. However, I will assume by "class method" you meant "an instance method defined on the singleton class of a Class instance" and by "module method" you meant "an instance method defined on the singleton class of a Module instance".

There is no functional difference between the two. Both define a method within a namespace.

In practice, you'll see that they tend to be used for different purposes. For example, class methods are often to specify different ways to construct an object, e.g. Puzzle.from_textfile. Module methods are just global functions that are put into a single namespace because they are logically related, e.g. Math.sin and Math.abs.

It's also important to note that Ruby also has the concept of a "module function", which is unrelated to this question. The term "module function" refers an class method on a module which has an identical private instance method. These can be created programmatically using Module.module_function, and are useful when a module is intended to be used as both a namespace and a mixin (e.g. Math).

Ceasar
  • 22,185
  • 15
  • 64
  • 83
1

Modules are about providing methods that you can use across multiple classes - think about them as "libraries" (as you would see in a Rails app). Classes are about objects; modules are about functions

See this

Community
  • 1
  • 1
Tony Vincent
  • 13,354
  • 7
  • 49
  • 68
  • An example of a module that contains only module methods (no instance methods to be mixed in with a class' instance methods by `include`-ing the module) is Ruby's [Math](http://ruby-doc.org/core-2.3.0/Math.html) module. Module methods are sometimes referred to as "helper" methods. – Cary Swoveland Jul 16 '16 at 05:34
0

Modules are similar to classes in that they hold a collection of methods, constants, and other module and class definitions. Unlike classes, you cannot create objects based on modules.

Modules serve two purposes. First, they act as a namespace, letting you define methods whose names will not clash with those defined elsewhere. Second, they allow you to share functionality between classes—if a class mixes in a module, that module’s instance methods become available as if they had been defined in the class. Multiple classes can mix in the same module, sharing the module’s functionality without using inheritance. You can also mix multiple modules into a single class.

Classes are to create objects.

Vadim Eremeev
  • 470
  • 5
  • 16
  • It's not necessary for a class to `include` a module to invoke one its module methods. They are simply referenced directly; for example, `x = Math.sqrt(2)`. – Cary Swoveland Jul 16 '16 at 05:50
  • Oh yes, thanks for your comment. Can also do this way – Vadim Eremeev Jul 16 '16 at 12:23
  • My point is that when you `include` a module only the instance methods are included; Ruby just skips over module methods, so `include` is irrelevant here. – Cary Swoveland Jul 16 '16 at 17:00
  • 1
    This question is asking about the difference between module methods and class methods, not modules and classes. – Ceasar May 18 '18 at 22:14