Rails: I can't call a function in a module in /lib - what am I doing wrong?

If you want Module-level functions, define them in any of these ways:

module Foo
  def self.method_one
  end

  def Foo.method_two
  end

  class << self
    def method_three
    end
  end
end

All of these ways will make the methods available as Foo.method_one or Foo::method_one etc

As other people have mentioned, instance methods in Modules are the methods which are available in places where you've included the Module


I'm going to try to summarise the various answers myself, since each had something valuable to say, but none really got to what I now realise is probably the best response:

I was asking the wrong question because I was doing it wrong.

For reasons I can no longer explain, I wanted a set of completely stand-alone functions in a library, which represented methods I was trying to DRY out of my classes. That can be achieved, using things like

module Foo
  def self.method_one
  end

  def Foo.method_two
  end

  class << self
    def method_three
    end
  end

  def method_four
  end

  module_function :method_four
end

I could also include my module, either within a class, in which case the methods become part of the class or outside, in which case they are defined on whatever class I'm running inside (Object? Kernel? Irb, if I'm interactive? Probably not a great idea, then)

The thing is, there was no good reason not to have a class in the first place - I'd somehow got on to a train of thought that took me down an seldom-used and frankly slightly weird branch line. Probably a flashback to the days before OO became mainstream (I'm old enough that up to today I've spent a lot more years writing procedural code).

So the functions have moved into a class, where they seem pretty happy, and the class methods thus exposed are being cheerfully used wherever necessary.


You can also use module_function like so:

module TestFunctions
  def abc
    puts 123
  end

  module_function :abc
end

TestFunctions.abc  # => 123

Now you can include TestFunctions in class and call "abc" from within TestFunctions module.