I would like to write my own isopen
function and therefore not import Base.isopen
. I have thought of two ways to do this:
module MyModule
function isopen end
# Lots of code...
include("file_that_defines_isopen.jl")
end
and
baremodule MyModule
import Base: Base, include, @__MODULE__, foreach, filter, names, Meta, β
eval(x) = Core.eval(@__MODULE__, x)
include(x) = include(@__MODULE__, x)
foreach(x->eval(Meta.parse("import Base: $x")), filter(β([:isopen]), names(Base)))
# Lots of code...
include("file_that_defines_isopen.jl")
end
Even though the first version is shorter, I still prefer the clarity of the second version, but unfortunately it fails for symbols like '
. Is there a way to get the second version to work or is there a third version that is even better?
I finally got it to work with the following code:
baremodule MyModule
import Base: Base, @eval, @__MODULE__, foreach, filter, names, β
eval(x) = Core.eval(@__MODULE__, x)
include(x) = Base.include(@__MODULE__, x)
foreach(filter(β([:isopen]), names(Base))) do sym
@eval import Base: $(sym)
end
# Lots of code...
include("file_that_defines_isopen.jl")
end
I think it would be better to utilize multiple dispatch, i.e. to define your own type and define your own version of isopen
for it.
2 Likes
In my case, I feel that this would be punning. The docstring for isopen
seems to be intended for streams and things like that. In my case, I want to use it for querying if a market was open at a specific time. I feel that these two uses are so different that I do not wish to just make another method for Base.isopen
, but rather make a MyPackage.isopen
function. By not importing it, I am doing what I can to avoid confusion without having to use another name. I do also require using my own type as one of the arguments, so erroneous use should throw an exception.
Then maybe it is better to use a much explicit name to avoid any confusion, such as ismarketopen
.
2 Likes
I think itβs fairly common to just have your function public but not exported, so that isopen
is for streams and MyPackage.isopen
is for your type.
Of the two approaches in the original post, the first seems much more idiomatic to me and also much safer. What was the issue with the first approach?
A huge hazard of import
ing all the methods in Base
is that any function you define that happens to coincide with an import
ed Base
function (in this case every public function, of which there are currently more than 1000) will add a method to the Base
version instead of defining a new function (because an explicitly imported function does not require namespace qualification to extend). And note that more public functions will be added to Base
in the future. Which means at any point in the future (if not present), you might accidentally pirate Base
functions and break something in a hilarious or not-so-hilarious way.
1 Like