How to include my module file as a package?

A possible quick-and-dirty fix ?

A fix for what? This ignores the core of the problem.

If this code bit is employed in two different modules A and B, then name_module will probably not be defined in both and, consequently, name_module will be included and defined in both causing the problem of two structs with the same name and fields being recognized as different types (because one is, in fact, A.name_module.MyStruct and the other is B.name_module.MyStruct, they are not the same thing).

If this code bit is employed multiple times inside the same module then the if is unnecessary, and an evidence of sloppy code.

There is no solution besides understanding what you are doing.

2 Likes

You are right in that it would not work across multiple modules. However, in the same module, in case of multiple sequences “include(“x.jl”);using .x”, it prevents redefinition of the module - eg possible frequent mistaken action in REPL workflow?

Concerning sloppy code, sorry, I already said “quick-and-dirty”… and, as you say, for best result, it all depends of what OP wants to do!

I apologize, I forgot this thread has month-old previous comments in which includeing code in the REPL was relevant. I was thinking only about code organization in projects/packages, and the REPL is a case I had not considered, I admit.

The REPL redefinition is quite the pernicious case:

julia> module A; struct S; x :: Int; end; end;

julia> first_s = A.S(10)
Main.A.S(10)

julia> module A; struct S; x :: Int; end; end;
WARNING: replacing module A.

julia> second_s = A.S(10)
Main.A.S(10)

julia> first_s == second_s
false

However, it seems to me that for your suggestion to work then the if statement would need to be outside the outermost module, what makes it easy to forget, maybe doing:

# MyModule.jl file
if @isdefined MyModule
    @warn "You have already imported MyModule, avoiding redefinition. If you want to redefine it then include my_module.jl instead."
else
    include("my_module.jl")
end # if !@isdefined MyModule

import .MyModule
---------------------------------------------------
# my_module.jl file
module MyModule
struct S
  x :: Int 
end
end # module

is an alternative you will not forget about. Using this alternative you get:

julia> include("MyModule.jl")

julia> first_s = MyModule.S(10)
Main.MyModule.S(10)

julia> include("MyModule.jl")
┌ Warning: You have already imported Main, avoiding redefinition. If you want to redefine it include my_module.jl instead.
└ @ Main ~/AreaDeTrabalho/MyModule.jl:3

julia> second_s = MyModule.S(10)
Main.MyModule.S(10)

julia> first_s == second_s
true

But for code organization the project/package writer will simply need to know what they are doing. I kept an warning mostly to make sure this trick would not be forgotten and cause even more headache.

1 Like

Good trick to use this double indirection. However I do not quite get why you use require rather than include. Would you care to elaborate somewhat about this choice?

1 Like

Fixed. require instead of include was a brainfart.