Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a module saved in /lib as test_functions.rb that looks like this

module TestFunctions   def abc     puts 123   end end 

Going into ruby script/runner, I can see that the module is loading automatically (good ol' convention over configuration and all that...)

>> TestFunctions.instance_methods => ["abc"] 

so the method is known, let's try calling it

>> TestFunctions.abc NoMethodError: undefined method `abc' for TestFunctions:Module from (irb):3 

Nope. How about this?

>> TestFunctions::abc NoMethodError: undefined method `abc' for TestFunctions:Module from (irb):4 

Test Nope again.

defined?(TestFunctions::abc) #=> nil, but TestFunctions.method_defined? :abc #=> true 

Like I said at the top, I know I'm being dumb, can anyone de-dumb me?

like image 604
Mike Woodhouse Avatar asked Mar 06 '09 18:03

Mike Woodhouse


People also ask

How do you call a method in a module?

The method definitions look similar, too: Module methods are defined just like class methods. 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.

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 call method in Rails?

It is used to call back a piece of code that has been passed around as an object.

How do I add a module in Rails?

You can include a module in a class in your Rails project by using the include keyword followed by the name of your module.


2 Answers

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

like image 91
Gareth Avatar answered Sep 23 '22 21:09

Gareth


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.

like image 39
Mike Woodhouse Avatar answered Sep 21 '22 21:09

Mike Woodhouse