Normally if I don't want all the exported names from a module I use import SomeModule
and access certain names with SomeModule.somename
, or sometimes to avoid verbosity, using SomeModule: somename
.
Just recently I saw a pattern new to me, using SomeModule: SomeModule
. Is there any difference between this and simply import SomeModule
? And is there any difference between import SomeModule: somename
and using SomeModule: somename
?
Yes, there is - import
allows extension of somename
with more methods, while using
does not
using SomeModule: SomeModule
is like import SomeModule
light - it only brings SomeModule
into scope, but without making the names exported from SomeModule
available for implicit extension without the SomeModule
prefix
Yeah, IMO using SomeModule: SomeModule
should typically be preferred over import
.
Ok that makes some sense; I guess a good way to remember is using = "I just want to use". @Mason Protter I assume what you're saying applies to using
/import
of names as well, i.e. usually using SomeModule: somename
unless somename
is to be extended.
I'd even use it if I'm extending somename
personally
E.g. if I have MyType
, I would never write
import Base: show
function show(::IO, ::MyType)
...
end
I would always write
function Base.show(::IO, ::MyType)
...
end
This way it's clear at the function definition site that I'm extending a function that didn't originate here.
:100: ... in the second example you'd still need using Base: Base
, no? (well, maybe not Base
since I guess that's already in scope)
.. or does it need to be import SomeModule; SomeModule.methodbeingextended() = ...
?
Yeah, if it was another package, the package name needs to be in scope.
using SomeModule: SomeModule, somefunction, anotherfunction
SomeModule.methodbeingextended() = ...
is my preferred pattern.
Patrick Bouffard has marked this topic as resolved.
Patrick Bouffard has marked this topic as unresolved.
So in what situations is import SomeModule
needed? Is it in effect the same as using SomeModule: SomeModule
?
You can define new methods on functions that have been imported without explicitly declaring the parent module, which is a very dangerous foot-gun.
Agreed, and also a lot less clear.
see also https://github.com/JuliaLang/julia/issues/39235
Expanding Man said:
You can define new methods on functions that have been imported without explicitly declaring the parent module, which is a very dangerous foot-gun.
I don't believe exports are put in scope when you use import SomeModule
sans colon, only using
?
You do have to explicitly import
the specific functions, but the problem is the same.
I guess some might argue that because the functions are import
ed explicitly it should not be confusing, but I used to do this and have spent a day debugging utterly bewildering bug I caused this way so now I never, ever do it.
I'm inclined to agree. Maybe a good custom linter rule (once such a linter exists)
To me the issue is not so much the risk that you might do this accidentally, but that if you do the failure mode will potentially be very weird.
Patrick Bouffard has marked this topic as resolved.
If you feel that the implicit extension stuff is dangerous, please do comment on the issue I linked, since that is part of the stuff that may be kept once this is tackled eventually
Last updated: Nov 06 2024 at 04:40 UTC