Methods imported from submodules are overwritten, not extended

I assumed that by defining different argument requirements I would get different methods for an already imported function from a submodule, but it seems I am getting an overwrite instead of an extension. What’s the idiomatic way of achieving this? I know about the @reexport macro, but I only want to achieve this selectively and I prefer to minimize dependencies.

Here’s a MWE:

module ParentModule

export test_func

struct Astruct
end


module SubModule

export test_func

struct Bstruct
end

test_func(b::Bstruct) = println("method B")

end


using .SubModule

 test_func(a::Astruct) = println("method A")

end

When we write test_func on the REPL to see the available methods:

julia> using .ParentModule

julia> test_func(
test_func(a::Main.ParentModule.Astruct) in Main.ParentModule at REPL[1]:24

If we repeat the same exercise, having commented the definition inside ParentModule, we get the method defined inside the submodule:

julia> module ParentModule

       export test_func


       struct Astruct
       end



       module SubModule

       export test_func

       struct Bstruct
       end

       test_func(b::Bstruct) = println("method B")

       end

       using .SubModule

       # test_func(a::Astruct) = println("method A")

       end
Main.ParentModule

julia> using .ParentModule

julia> test_func(
test_func(b::Main.ParentModule.SubModule.Bstruct) in Main.ParentModule.SubModule at REPL[1]:18

You either have to

      import .SubModule2: test_func2

      test_func2(a::Astruct) = println("method A")

or explicitly specify that you’re overriding SubModule’s function:

       using .SubModule

       SubModule.test_func(a::Astruct) = println("method A")
1 Like

See also:

1 Like

Thank you, I had not realized the extensible vs in-scope differences.