Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I invoke an instance method on a Ruby module without including it?

People also ask

How do you call a method in a module in Ruby?

As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons.

CAN modules have instance variables Ruby?

Explanation: Yes, Module instance variables are present in the class when you would include them inside the class.

Can you call an instance method in a class method Ruby?

In Ruby, a method provides functionality to an Object. A class method provides functionality to a class itself, while an instance method provides functionality to one instance of a class. We cannot call an instance method on the class itself, and we cannot directly call a class method on an instance.

How do you access a module method in Ruby?

A user cannot access instance method directly with the use of the dot operator as he cannot make the instance of the module. To access the instance method defined inside the module, the user has to include the module inside a class and then use the class instance to access that method.


I think the shortest way to do just throw-away single call (without altering existing modules or creating new ones) would be as follows:

Class.new.extend(UsefulThings).get_file

If a method on a module is turned into a module function you can simply call it off of Mods as if it had been declared as

module Mods
  def self.foo
     puts "Mods.foo(self)"
  end
end

The module_function approach below will avoid breaking any classes which include all of Mods.

module Mods
  def foo
    puts "Mods.foo"
  end
end

class Includer
  include Mods
end

Includer.new.foo

Mods.module_eval do
  module_function(:foo)
  public :foo
end

Includer.new.foo # this would break without public :foo above

class Thing
  def bar
    Mods.foo
  end
end

Thing.new.bar  

However, I'm curious why a set of unrelated functions are all contained within the same module in the first place?

Edited to show that includes still work if public :foo is called after module_function :foo


Another way to do it if you "own" the module is to use module_function.

module UsefulThings
  def a
    puts "aaay"
  end
  module_function :a

  def b
    puts "beee"
  end
end

def test
  UsefulThings.a
  UsefulThings.b # Fails!  Not a module method
end

test

If you want to call these methods without including module in another class then you need to define them as module methods:

module UsefulThings
  def self.get_file; ...
  def self.delete_file; ...

  def self.format_text(x); ...
end

and then you can call them with

UsefulThings.format_text("xxx")

or

UsefulThings::format_text("xxx")

But anyway I would recommend that you put just related methods in one module or in one class. If you have problem that you want to include just one method from module then it sounds like a bad code smell and it is not good Ruby style to put unrelated methods together.


To invoke a module instance method without including the module (and without creating intermediary objects):

class UsefulWorker
  def do_work
    UsefulThings.instance_method(:format_text).bind(self).call("abc")
    ...
  end
end