user1032752
user1032752

Reputation: 881

Ruby - Including two modules that both have a sub-module with the same name

I have two modules, Foo and Bar. Each has a namespaced module called Errors that contains error classes as so:

module Foo
  module Errors
    class FooError < StandardError
      def initialize
        super "I'm a FooError"
      end
    end
  end
end

module Bar
  module Errors
    class BarError < StandardError
      def initialize
        super "I'm a BarError"
      end
    end
  end
end

I want to include both of these modules in my class called Baz and be able to access both Errors modules. As so:

class Baz
  include Foo
  include Bar

  p Errors::FooError.new
  p Errors::BarError.new
end

Ruby throws an error uninitialized constant Bar::Errors::FooError when trying to instantiate FooError but not for BarError.

Am I understanding correctly that the Bar::Errors module is overwriting the Foo:Errors module? How do I prevent that from happening/accomplish being able to reference both types of errors from within Baz?

Thanks!

Upvotes: 1

Views: 2402

Answers (1)

Max
Max

Reputation: 22365

You can always rename modules to not conflict:

Foo::FooErrors = Foo::Errors
Bar::BarErrors = Bar::Errors

Or you could skip the conflicting modules and go straight to including the error classes you want:

class Baz
  include Foo::Errors
  include Bar::Errors
end

Or don't bother including anything and use the full names:

p Foo::Errors::FooError.new
p Bar::Errors::BarError.new

In my opinion, include is too often used as a convenience method to avoid typing module names. This usage is not really necessary and can introduce errors (as you've seen) or ambiguity. There are some things that you can only accomplish using include (like adding instance methods from a module), but most uses I see don't fall in that camp.

Upvotes: 4

Related Questions