doremi
doremi

Reputation: 15349

Extend class in same module with class methods defined in module

I have a module with some class methods I'd like to make available to classes within the module. However, what I'm doing is not working.

module Foo
  class << self
    def test
      # this method should be available to subclasses of module Foo
      # this method should be able to reference subclass constants and methods
      p 'test'
    end
  end
end

class Foo::Bar
  extend Foo
end

This fails:

Foo::Bar.test
NoMethodError: undefined method `test'

What am I doing wrong?

Upvotes: 4

Views: 225

Answers (1)

Cary Swoveland
Cary Swoveland

Reputation: 110755

When you extend a module from a class, the module's instance methods become class methods in the class. So you need:

module Foo
  def test
    puts "hi"
  end
end

class Foo::Bar
  extend Foo
end

Foo::Bar.test #=> hi

If you'd also like to have a module method Foo::test, which can be called from anywhere with Foo.test, change the above to:

module Foo
  def test
    puts "hi"
  end
  extend self
end

Foo::Bar.test #=> hi
Foo.test      #=> "hi"

Upvotes: 3

Related Questions