When to Use Self in Module's Methods

When to use self in module's methods

Use self in each method definition if you want the methods to be defined only in the singleton class of the module (where the methods defined using self live). Omit self and extend self if you want the methods of the module to be defined as instance methods and singleton methods at the same time.

For instance, you can call the method using RG::Stats.sum(array) and still have it listed by the instance_methods method if you do this:

module RG::Stats
extend self

def sum(a, args = {})
a.inject(0){ |accum, i| accum + i }
end
end

This way, the sum method is defined as an instance method and it is included in the singleton class of the module after using extend self.

You can check the instance methods of RG::Stats module to verify this:

RG::Stats.instance_methods
=> [:sum]

With this technique you don't have to worry about defining the method without the self keyword because modules can't have instances so it cannot be called like an instance method of RG::Stats module. It can only be called as a singleton method RG::Stats.sum(array) thanks to the extend self statement.

Using self in modules

The difference is that first example defines module method called preview, and second example defines mixin method preview.

So that if you include first module into a class, you'll be able to call this method on the class (whereas calling the method on the class instance would cause the error), while including the second module into the class will allow you to call the method on class' instances, but calling the method on the class itself will cause

NoMethodError: undefined method preview for Foo:Class

Regarding conflicts basing on the same method name in class and module included to it. Answer to this question lays in Ruby method lookup, which is following:

  1. Methods from the object's singleton/meta/eigen class
  2. Methods from prepended modules (Ruby 2.0+ feature)
  3. Methods from the object's class
  4. Methods from included modules
  5. Methods from the class hierarchy (superclass and its ancestors)

Method lookup stops, when the method is found.

With prepend the mixin method will have precedence in method lookup;

With include method defined in class has the precedence in method lookup.

So no conflicts are possible.

When to use a class vs. module extending self in Crystal?

There is not much difference between class and module regarding definition of class methods. They are however fundamentally different in the fact that a class defines a type that can be instantiated (Service.new). Modules can have instance methods as well, but they can't be instantiated directly, only included in a class.

If you only need a namespace for class methods, you should use module. class would work fine for this too, but conveys a different meaning.

Btw: While you can't extend or include a class, in a module you can write def self.get instead of extend.

(Ruby,Rails) Context of SELF in modules and libraries...?

In a module:

When you see self in an instance method, it refers to the instance of the class in which the module is included.

When you see self outside of an instance method, it refers to the module.

module Foo
def a
puts "a: I am a #{self.class.name}"
end

def Foo.b
puts "b: I am a #{self.class.name}"
end

def self.c
puts "c: I am a #{self.class.name}"
end
end

class Bar
include Foo

def try_it
a
Foo.b # Bar.b undefined
Foo.c # Bar.c undefined
end
end

Bar.new.try_it
#>> a: I am a Bar
#>> b: I am a Module
#>> c: I am a Module

When do you use 'self' in Python?

Adding an answer because Oskarbi's isn't explicit.

You use self when:

  1. Defining an instance method. It is passed automatically as the first parameter when you call a method on an instance, and it is the instance on which the method was called.
  2. Referencing a class or instance attribute from inside an instance method. Use it when you want to call a method or access a name (variable) on the instance the method was called on, from inside that method.

You don't use self when

  1. You call an instance method normally. Using Oskarbi's example, if you do instance = MyClass(), you call MyClass.my_method as instance.my_method(some_var) not as instance.my_method(self, some_var).
  2. You reference a class attribute from outside an instance method but inside the class definition.
  3. You're inside a staticmethod.

These don'ts are just examples of when not to use self. The dos are when you should use it.

Using class self, when to use classes or modules?

The class<<self seems to be a red herring, as the only difference here is a class versus a module. Perhaps you're asking "I want to create an object that I do not intend to instantiate, but which exists only as a namespace for some methods (and possibly as a singleton with its own, global, state)."

If this is the case, both will function equally well. If there is any chance that you might want to create a derivative (another object inheriting the same methods) then you should use a class as it slightly is easier to write:

class Variation < Helper

instead of

module Helper
module OwnMethods
# Put methods here instead of class << self
end
extend OwnMethods
end

module Variation
extend Helper::OwnMethods

However, for just namespacing I would generally use a module over a class, as a class implies that instantiation will occur.

self.included in a module

As you're including SimpleURLSanitizer in a class, all the methods of SimpleURLSanitizer will be accessible as instance method. This is the default behavior.

The included part is also making sure that, you can access those methods as class methods.

self.included – including class methods from a module in Ruby

What's the difference between the two examples?

The first code block adds the class methods in ClassMethods to the including class and calls the scope method on it as well. The second one does neither of these things and will result in a NoMethodError because the module has no scope class method. self.some_class_method will not be available on the including class once the module is included.

For the full story on how module inclusion works in Ruby, read my answer here:

Inheriting class methods from modules / mixins in Ruby

What's the point of self.included if a module's sole purpose is to be included?

Inclusion is not the only purpose of modules. They are also used for other things such as namespacing or simply storing various class methods that are then callable on the module itself.

Why doesn't Ruby include class methods automatically?

Theoretically Ruby could automatically add all class methods defined in a module to the including class, but in practice that would be a bad idea, because you would not get to choose anymore whether you want to include class methods — all class methods would be included every time, whether or not they are intended to be included. Consider this example:

module M
def self.class_method
"foo"
end

def self.configure_module
# add configuration for this module
end
end

class C
include M
end

Here, the configure_module method is obviously not supposed to be added to C, as its purpose is to set the configuration for the module object. Yet, if we had auto-inclusion for class methods, you would not be able to prevent it from being included.

But all instance methods are already included! How is that okay then?

Instance methods in a module are only really useful if they are included into a class, since modules cannot have instances, only classes can. So in a module every instance method is expected to be included somewhere to work.

A "class" method on a module is different, because it can be called on the module itself, so it can be used just fine regardless of whether it's also added to the including class. That is why it is better that you have a choice there.



Related Topics



Leave a reply



Submit