Can not cahnge variables defined in an external file

Let us assume that I define some variables in a separate file “input.jl”.
For example, let the content of “input.jl” be

a = 123.0

Then, I want to use the name of this file as an input parameter to dynamically load the above variables through include:

module MyModule

function run(fname)
    include(fname)
    
    @show a
    b = a / 2.0
    # a = a / 2.0

    return nothing
end

end


import .MyModule

MyModule.run("input.jl")

After running this script I see

a = 123.0

However, If I uncomment the line with “a = a / 2.0”, I obtain the following error message:

ERROR: LoadError: UndefVarError: a not defined

Thus, it seems that I can not change a variable included from external file.
Can you, please, explain me why it happens.

Thank you.

Include runs in global scope and you get the error because the assignment makes a local.

There is no function to include a file locally with a runtime filename.

1 Like

Thank you.

Leaving aside the include(fname) situation, this will also happen if you define a as a variable inside the module:

module MyModule
a=123.0
function run(fname)
    a = a / 2.0
    return nothing
end
end

Shouldn’t the error message be a bit more informative? Something like: Cannot reassign "a"(defined in global scope of MyModule) in local scope.

The error message can potetially be improved but wha you give is not the issue. It is perrfectly fine to assign to a global, you just need to define it. Here a is a local variable in run so it doesn’t have a value before you assigned it.

1 Like

What yuyichao means is that you need to do:

module MyModule
a=123.0
function run(fname)
    global a
    a = a / 2.0
    return nothing
end
end

If you not do this, then the error message is just exactly the problem, there is no a define in local scope. Maybe the code for the error could do something like checking all the global names for the same name (or a very similar one) and suggest using global if it is the case. But I do believe it would be expected that a programmer facing this error searched for “julia scoping rules” to understand why a is not available at the method scope and discovered the keyword global.

Maybe the error message could be changed to ERROR: LoadError: UndefVarError: a not defined. If a is a global variable referred in local scope please prefix the first mention to the variable in the local scope with the keyword global., but most of the time this is probably not the problem, and would only make novice programmers more confused.

1 Like

I am aware of the scope rules and that one needs to use global. I just wanted to point out the error message could be a bit more friendly. I actually like your version of error message.

Oh, sorry, I thought that I was replying to the person that initially asked the question (@fedoraoff), XD.

Well, you can suggest the error message to the Julia developers, but I really think it becomes kinda long and potentially confusing for newcomers. Probably the most common error is just having a typo in the variable name, and this is not mentioned in the error message. If the error message needs to consider all the most common reasons it will become very large. There was an idea discussed here on Discourse about creating a package that would improve on error messages and could be installed by newcomers as a training wheel while they are learning the language, but initially the idea was to use the dynamic dispatch and define error messages to operators/method calls that people expected to be defined for some type parameters but are not, and suggest the right method/operator for that situation.