# How to extend different internal methods based on the module I load?

**URL:** <https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661>\
**Category:** General Usage\
**Tags:** question, development\
**Created:** [June 3, 2020, 11:51am UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661 "2020-06-03T11:51:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [June 3, 2020, 11:51am UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661/1 "2020-06-03T11:51:45Z")

</div>

For example, if I have a function `outer` that has an internal implementation `inner`, and I want to extend `inner` in different modules.

```julia
module Outer

export outer

function outer(a, b)
    # do something
	print(methods(inner))
    return inner(a, b)
end

function inner end

module A

import ..Outer

Outer.inner(a, b) = a + b

end

module B

import ..Outer

Outer.inner(a, b) = a * b

end

end

```

As you can see, `outer` is my public API. And I want it to behave differently if I load different modules. Usually, I can define 2 methods on the types of args `a` and `b`. But in this example, `a` and `b` have fixed types, so no dispatch on types. The expected behavior is that if I load `A`, `outer(1, 2) -> 3`, and once I write `using Outer.B` in the same REPL environment, `outer(1, 2) -> 2`.

```julia
julia> using .Outer

julia> outer(1, 2)
# 1 method for generic function "inner":
[1] inner(a, b) in Main.Outer.B at REPL[1]:252

```

If I invoke `outer`, `inner` defined in `A` is rewritten by that defined in `B`. I tried `Base.invokelatest` and it gave the same result.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 3, 2020, 12:18pm UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661/2 "2020-06-03T12:18:51Z")

</div>

> [@singularitti](#):
>
> `outer` is my public API. And I want it to behave differently if I load different modules.

Don’t do this. It does not mesh well with how Julia works, and it is bad style.

Instead, you could use a parameter to `outer` that is passed to `inner` and participates in dispatch.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [June 3, 2020, 1:35pm UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661/3 "2020-06-03T13:35:05Z")

</div>

Traditionally this would be done if module B implemented a custom object that it wanted processed by module A . Like:

```julia
module B
   import ..Outer

   struct BbObj
   end
   
    Outer.inner(a::BbObj, b) = # whatever needs to happen.
end

```

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [June 3, 2020, 2:04pm UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661/4 "2020-06-03T14:04:57Z")

</div>

Yes, but I cannot do that. For example, let’s say `outer` takes `a::Int` and `b::Int`. So there’s no way to distinguish the two `inner`s using type-based dispatch. What I am trying to do is like dispatch `inner` on module name `A` and `B`.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [June 3, 2020, 3:38pm UTC](https://discourse.julialang.org/t/how-to-extend-different-internal-methods-based-on-the-module-i-load/40661/5 "2020-06-03T15:38:05Z")

</div>

If two methods are named the same and take the same parameters, then there is no way to distinguish between the two, and the one that is most recently defined will “win” and be the method that is called.

If you need to do that then you need to pass in the function in the method call so it can be called back.
