Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is defining a module function with `module_function` the same as defining it with `self.` in Ruby?

Tags:

ruby

Is defining a module function with module_function the same as defining it with self. in Ruby? That is, do they both result in the creation of both instance and module methods?

like image 624
Keith Bennett Avatar asked May 04 '16 07:05

Keith Bennett


People also ask

What is self in a Ruby module?

self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup. When defining methods, classes and modules.

What is Module_function in Ruby?

module_function(*args) private. Creates module functions for the named methods. These functions may be called with the module as a receiver, and also become available as instance methods to classes that mix in the module. Module functions are copies of the original, and so may be changed independently.

What is module function in Ruby on Rails?

A Module is a collection of methods, constants, and class variables. Modules are defined as a class, but with the module keyword not with class keyword. Important Points about Modules: You cannot inherit modules or you can't create a subclass of a module. Objects cannot be created from a module.

What is the difference between modules and classes in Ruby?

What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).


2 Answers

No.

module M1
  def self.foo; end
end

module M2
  module_function
  def goo; end
end

M1.methods(false)           #=> [:foo] 
M1.instance_methods         #=> [] 
M1.private_instance_methods #=> [] 

M2.methods(false)           #=> [:goo] 
M2.instance_methods         #=> [] 
M2.private_instance_methods #=> [:goo] 
like image 183
Cary Swoveland Avatar answered Sep 19 '22 14:09

Cary Swoveland


No, they are not the same. Using self. creates only a module method, whereas module_function creates both a module and an instance method:

#!/usr/bin/env ruby

module M1
  def self.foo
    puts 'foo'
  end
end

module M2
  module_function
  def foo
    puts 'foo'
  end
end


class C1
  include M1

  def test
    puts 'Call M1 as module method:'
    M1.foo
    # puts 'Call M1 as instance method:'
    # foo
  end
end

class C2
  include M2

  def test
    puts 'Call M2 as module method:'
    M2.foo
    puts 'Call M2 as instance method:'
    foo
  end
end

C2.new.test; C1.new.test

Results in the following output:

Call M2 as module method:
foo
Call M2 as instance method:
foo
Call M1 as module method:
foo

If you then uncomment out the 'Call M1 as instance method:' 2 lines, you'll see this error:

./m1.rb:24:in `test': undefined local variable or method `foo' for #<C1:0x007feb311767f8> (NameError)

This shows that an instance method foo was not created when the method was defined as self.foo.

like image 29
Keith Bennett Avatar answered Sep 21 '22 14:09

Keith Bennett