2

I'm writing some class inside module:

module A
end

module A::B
  def foo
    print "foo"
  end
end

class A::B::C
end

A::B::C.new.foo # => NoMethodError: undefined method `foo' for #<A::B::C...>

How can I define method in module B to call in the class C?

nub
  • 474
  • 1
  • 7
  • 16

3 Answers3

4

It is as if you write:

module A::B
  def foo
    print "foo"
  end

  class C
  end
  print 'C.instance_methods : '; p C.instance_methods(false)
  #=> C.instance_methods : []
end

C does not automatically inherits foo. There are only two ways to inherit instance methods:

  1. class C < super_class where super_class is an expression returning a class

  2. Including a module:

    class C
      include <some module>
    

For an explanation of the superclass chain, see How does Inheritance work in Ruby? and Ruby: Module, Mixins and Blocks confusing?

Community
  • 1
  • 1
BernardK
  • 3,674
  • 2
  • 15
  • 10
3

Namespaces in Ruby don’t work the way you seem to think.

  1. There is no such thing as a “namespace method”. A::B#foo is an instance method on the module A::B—which is a module named B in the namespace of A.

  2. Namespaces modules/classes have no special relationship of inheritance between them. They are purely organizational in nature, except when defined the long way (e.g. module A; module B; end; end) when they can affect lexical scope.

If you want to get methods of A::B in A::B::C, you must include A::B in A::B::C, just like you would anywhere else. You have to do this because, as said above, there's nothing special about a namespaced module/class, it is treated the same as any other.

Community
  • 1
  • 1
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
2
class A::B::C
  include A::B
end
sawa
  • 165,429
  • 45
  • 277
  • 381