0

Under Ruby 2.0, what is the correct way to access a module method from a class in that module?

For instance, if I have

module Foo
    class Foo
        def do_something
            Foo::module_method
        end
    end

    def self.module_method
        puts 'How do I call this?'
    end
end 

I get,

./so-module.rb:7:in do_something': undefined methodmodule_method' for Foo::Foo:Class (NoMethodError) from ./so-module.rb:16:in `'

What is the correct way to define the module method so I can access it from class Foo?

James McMahon
  • 48,506
  • 64
  • 207
  • 283
  • Are you sure that’s the error you’re getting? I get “NoMethodError: undefined method `module_method' for Foo:Module”. – Andrew Marshall Dec 05 '13 at 17:16
  • @AndrewMarshall, you're right, something was lost in translation from my actual code to simplifying it down to an example. Let me see if I can figure it out. – James McMahon Dec 05 '13 at 17:58
  • Ah ok, I also had a problem with the class name being the same as the module name and that was causing weird stuff to happen, so I've corrected that. – James McMahon Dec 05 '13 at 18:20
  • Can you update your question to reflect the changes? – Andrew Marshall Dec 05 '13 at 18:28
  • I actually don't get the exact same error even with a changed script, but I will update it to reflect more closely my original problem – James McMahon Dec 05 '13 at 21:08

2 Answers2

1

You have to define the method on the module’s singleton class:

module Foo
  class Bar
    def do_something
      Foo.module_method
    end
  end

  def self.module_method
    'Success!'
  end
end

Foo::Bar.new.do_something  #=> "Success!"
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
0

Please take a look at following code:

module Foo
    class Bar
        include Foo
        def do_something
            module_method
        end
    end
    def module_method
        puts 'How do I call this?'
    end
end

b = Foo::Bar.new
b.do_something

result:

How do I call this?

You can even try adding following code:

b1 = Foo::Bar::Bar.new
b1.do_something

It's tricky and has same result:

How do I call this?
uncutstone
  • 408
  • 2
  • 11