module a
global test = "hi"
end
# Another file
module b
import a
a.test = "bye" # ErrorException("cannot assign variables in other modules")
end
Looks like it’s impossible to change GLOBAL variables or variables in general from other modules which is very weird in my opinion, are there any alternative to this?
There may be another way using eval, but here are 2 ways:
julia> module a
global test = Ref("hi")
end
Main.a
julia> module b
import Main.a
a.test[] = "bye"
end
Main.b
julia> a.test
Base.RefValue{String}("bye")
julia> module a
global test = "hi"
settest(t) = (global test = t)
end
WARNING: replacing module a.
Main.a
julia> module b
import Main.a
a.settest("bye")
end
WARNING: replacing module b.
Main.b
julia> a.test
"bye"
You can ignore the Main. if they are real packages.
Thank you very much, I got a question about the first way, what if I want to change from String to Dict? it will automatically error: ERROR: MethodError: Cannot convert an object of type Dict{String,String} to an object of type String
Yes and this is probably a good thing! In Julia variables taking multiple types are frowned upon. You can do global test = Base.RefValue{Union{String, Dict{String, String}}}("hi"), but that will reduce the performance of your code. Also it is better if you make it a constant.
julia> const test = Base.RefValue{Union{String, Dict{String, String}}}("hi")
Base.RefValue{Union{Dict{String,String}, String}}("hi")
julia> test[] = "bye"
"bye"
julia> test = "bye"
ERROR: invalid redefinition of constant test
Stacktrace:
[1] top-level scope at none:0
test can be a constant binding to a mutable object. So you can mutate the object it is bound to, but you cannot rebind it to another object. The second command is valid, the third is not, even if you try to bind it to another RefValue of the same type.
No. If you can accept solution that require changes of module a, than using a const global ref is way better. This is especially true if the type is known.