After a couple of months of using Julia, I’m still a little confused about how methods interact with packages/namespaces. That is, situations where a package adds additional methods to a function originally defined in another package.
If I have a package A
that defines (and exports) func
and another package B
that defines additional methods for func
, it seems like doing using A
and using B
in the REPL, I get the combined methods from A
and B
. This does not seem to depend on whether B
also exports func
. Is that officially how things are supposed to work: If I’m using A
, do all methods for func
defined in other packages that I might use directly or indirectly get merged in automatically? With “indirect” I mean if I’m using C
and the package C
has a uses B
, do I get the methods that B
defines for A.func
automatically?
Is there any way to use (parts of) B
but not use the methods that B
defines for A.func
? One might expect that if I do using A
and using B: func2
(where func2
is some unrelated function), I wouldn’t get B
’s method for A.func
, but in fact I do.
Second, while an explicit export
of func
in B
doesn’t seem to affect whether B
’s method for A.func
gets used or not, it does seem to have some effect when I’m not directly using the package A
that originally defines func
. If my package B
looks like this:
module B
import A
A.func(i::Int) = i
end
and I’m only using B
in the REPL but not using A
, then neither func
not B.func
is available. However, if my package B
reads
module B
import A: func
func(i::Int) = i
end
then using B
(without using A
) in the REPL does give me access to B.func
, and B.func
includes both the methods from A
and from B
.
If I further export func
, that is,
module B
import A: func
export func
func(i::Int) = i
end
then using B
in the REPL (again without using A
), gives me access to both func
and B.func
, again using the methods from both A
and B
.
Also, in that case, if I’m both using A
and using B
explicitly in the REPL, I can address func
as func
, A.func
, or B.func
, with all three being completely equivalent.
Lastly, if I define the package B
as
module B
import A
export func
A.func(i::Int) = i
end
I don’t get any complaints from Julia, but the REPL autocompletion thinks that both func
and B.func
exist, but then gives me an UndefVarError: func not defined
.
This last one seems like a bug. As for all the previous examples, they all seem okay, but I can’t say that I have a good mental model for why exactly they behave the way they do. Is there one?