4

I have a module A that describes a framework. Then, a couple of modules (here just B) that implement the framework. Finally, I want C to use any of the implementations.

However, running the following example:

module A
    abstract type Ab end

    f(::Ab) = "Not NotImplemented"
    export Ab, f
end

module B
    using Main.A
    struct Bb <: A.Ab end
    A.f(::Bb) = "B"
    export Bb, f
end

module C
    using Main.A
    struct Cc
        btype :: A.Ab
    end
    f(model::Cc) = f(model.btype)
    function g(model::Cc)
        @show f(model)
    end
    export Cc, g
end

using Main.A, Main.B, Main.C

ex0 = B.Bb()
ex1 = C.Cc(ex0)
g(ex1)

returns an error

ERROR: LoadError: MethodError: no method matching f(::Main.B.Bb)
Closest candidates are:
  f(::Main.C.Cc) at C:\Users\tangi\.julia\dev\VariationalInequalitySolver\script.jl:2

and I really don't want to have to import B in the module C to guarantee genericity.

BatWannaBe
  • 4,330
  • 1
  • 14
  • 23
Tanj
  • 442
  • 2
  • 9

1 Answers1

4

The problem is:

f(model::Cc) = f(model.btype)

in your C module as it creates a new function in module C that has name f.

You need to write:

A.f(model::Cc) = f(model.btype)

which creates a new method for function f from module A.

Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107
  • 1
    Which the OP did for module B not C, so OP's code is a few tweaks away from a concise demonstration of namespace hygiene! – BatWannaBe Nov 10 '21 at 08:50