# Extended method not being seen by original module

**URL:** <https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748>\
**Category:** General Usage\
**Created:** [July 30, 2018, 5:45pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748 "2018-07-30T17:45:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbmuir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbmuir/32/4798_2.png) [@jbmuir](https://discourse.julialang.org/u/jbmuir)\
**Post date:** [July 30, 2018, 5:45pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/1 "2018-07-30T17:45:44Z")

</div>

I’m trying to implement a custom linear operator in for the LowRankApprox package, and some of my method definitions are not interacting with the methods in that package; e.g.

> julia\> ishermitian(A::CovarianceOperator) = true  
> ishermitian (generic function with 2 methods)
> 
> julia\> A = CovarianceOperator(X)  
> CovarianceOperator{Float64}(1000, #1, Nullable{Array{Float64,N} where N}())
> 
> julia\> ishermitian(A)  
> true
> 
> julia\> pheigfact(A) #this is a function defined by LowRankApprox  
> ERROR: MethodError: no method matching ishermitian(::CovarianceOperator{Float64})

I expect that this issue is due to my own incomplete knowledge of the Julia module system or similar, so if anybody could set me straight, I would really appreciate it

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [July 30, 2018, 5:49pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/2 "2018-07-30T17:49:43Z")

</div>

You probably need to import the method before extending it, otherwise you are overriding it (you can see it has only two methods):

```julia
import LowRankApprox: ishermitian
ishermitian(A::CovarianceOperator) = true

```

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 30, 2018, 6:30pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/3 "2018-07-30T18:30:39Z")

</div>

Over time I have learned the lesson that when extending methods from other packages it is usually better to do this extension explicitly rather than using `import`. For example @jonathanBieler’s suggestion should work just fine, but you can also do

```julia
LowRankApprox.ishermitian(A::CovarianceOperator) = true

```

This will make it clear to anyone looking at your source code that `ishermitian` comes from `LowRankkApprox`, whereas the `import` may have been easy to miss, depending on where you put it. I’ve caused myself some embarrassing errors by changing a method I hadn’t realized was being `import`ed (as I recall I did this with `Base.write`, so you can imagine the hilarity that ensued).

---

<div class="post-metadata">

**Author:** ![jbmuir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbmuir/32/4798_2.png) [@jbmuir](https://discourse.julialang.org/u/jbmuir)\
**Post date:** [July 30, 2018, 6:35pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/4 "2018-07-30T18:35:34Z")

</div>

Ok, that seems to have solved the problem. I’m still a little confused though, since in the original case I had defined a method ishermitian, on CovarianceOperator - even if it overrode the original definition, shouldn’t it still work since presumably pheigfact only cares about getting ishermitian(::CovarianceOperator)? (when I say shouldn’t, clearly that is my mistake!)

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 30, 2018, 6:41pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/5 "2018-07-30T18:41:18Z")

</div>

Without an `import LowRankApprox: ishermetian` (or without explicitly defining your method as `LowRankApprox.ishermetian(...)` as @ExpandingMan suggests), you are creating a completely new function. The fact that that function shares its name with a function from `LowRankApprox` is completely coincidental and has no effect whatsoever. When someone (like, say, a function in LowRankApprox) calls `LowRankApprox.ishermetian`, the existence of your personal `ishermetian` function is of no consequence at all.

If you _do_ have the `import` (or explicit definition of `LowRankApprox.ishermetian`), then you are actually extending the _same_ function. So any calls to `LowRankApprox.ishermetian` (e.g. any calls from within `LowRankApprox`) will see your new method and choose it as appropriate.

I’d also second @ExpandingMan’s suggestion, as I find that explicit overloading is easier to reason about and less subject to non-local effects (in this case, the presence or absence of an `import ` somewhere else in the module).

---

<div class="post-metadata">

**Author:** ![jbmuir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbmuir/32/4798_2.png) [@jbmuir](https://discourse.julialang.org/u/jbmuir)\
**Post date:** [July 30, 2018, 6:45pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/6 "2018-07-30T18:45:59Z")

</div>

Thanks for the explanation - if I could ask one more style question; should this explicit overloading recommendation extend to functions in Base?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 30, 2018, 6:51pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/7 "2018-07-30T18:51:38Z")

</div>

> [@jbmuir](#):
>
> should this explicit overloading recommendation extend to functions in Base?

I would say _especially_ functions in `Base`. The two exceptions I can think of is if you are extending a “interface” package which exists for the purpose of you adding methods to it in other packages and perhaps in some metaprogramming situations where omitting the original module might simplify the code or make it more portable.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [July 30, 2018, 6:57pm UTC](https://discourse.julialang.org/t/extended-method-not-being-seen-by-original-module/12748/8 "2018-07-30T18:57:28Z")

</div>

You just need to be a little bit careful you are not overriding existing methods, but extending the function with a new type you defined; do `Base.length(x::SoccerField) = 110m` but not `Base.length(x::Vector) = 110m` (yes the example is maybe not the best because SoccerField is not a collection).
