Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to call a Module function from inside a class that is also in that module

Tags:

ruby

In this Ruby code:

Module M
  Class C < Struct.new(:param)
    def work
      M::helper(param)
    end
  end

  def helper(param)
    puts "hello #{param}"
  end
end

I get a "undefined method 'helper' for 'M:Module'" error when I try to run

c = M::C.new("world")
c.work

but calling M::helper("world") directly from another class works fine. Can classes not call Module functions that are defined in the same Module they are defined in? Is there a way around this other than moving the class outside of the module?

like image 941
Ryan Ahearn Avatar asked Jul 01 '10 16:07

Ryan Ahearn


People also ask

Can we use module inside class?

The user can use the module inside the class by using include keyword. In this case, the module works like a namespace.

How do you call a method from a module?

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 we define module inside class Ruby?

You can define and access instance variables within a module's instance methods, but you can't actually instantiate a module. A module's instance variables exist only within objects of a class that includes the module.

How do you use a function in a module?

You can use the functions inside a module by using a dot(.) operator along with the module name. First, let's see how to use the standard library modules. In the example below, math module is imported into the program so that you can use sqrt() function defined in it.


2 Answers

In order to invoke M::helper you need to define it as def self.helper; end For the sake of comparison, take a look at helper and helper2 in the following modified snippet

module M
  class C < Struct.new(:param)
    include M     # include module to get helper2 mixed in
    def work
      M::helper(param)
      helper2(param)
    end
  end

  def self.helper(param)
    puts "hello #{param}"
  end

  def helper2(param)
    puts "Mixed in hello #{param}"
  end
end

c = M::C.new("world")
c.work
like image 124
Gishu Avatar answered Oct 13 '22 00:10

Gishu


you should prepend module method with self:

module M
  class C < Struct.new(:param)
    def work
      M::helper(param)
    end
  end

  def self.helper(param)
    puts "hello #{param}"
  end
end
like image 22
Eimantas Avatar answered Oct 12 '22 23:10

Eimantas