How to detect globals (inadvertently used) in a function?

There is probably a simple answer, but it has somehow escaped me.

Is there a way to list the variables used in a function? In particular, I want to spot any globals that are inadvertently used.

a = 1
fn1(x) = a + x    #I really meant to make `a` an argument, but forgot. How do I catch this?

I’d like to hear about what good ways people have found, too. When I do find accidental globals, I tend to wish I fixed them earlier than trying out a @code_warntype ... and find the glaring red type instabilities next to a MyModule.accidental_global. @code_warntype also isn’t always clear about accidentally shared locals despite the obvious type instabilities.

Tools for that do exist, Traceur.jl is even pointed out in the Manual in Julia’s official documentation. Currently I prefer JET.jl, though:

julia> a = 1

julia> f(x) = a + x
f (generic function with 1 method)

julia> using JET

julia> @report_opt f(7)
═════ 1 possible error found ═════
β”Œ @ REPL[2]:1 Main.+(%1, x)
β”‚ runtime dispatch detected: Main.+(%1::Any, x::Int64)

Note that this is completely based on static analysis, but it’s possible to also use run time information with SnoopCompile.jl.


I also noticed that the VS code debugger shows locals/globals when stepping into a function.

If we are talking about a module:
I try to use as few globals as possible. It also helps if your globals have β€œclear” names, e.g. they could be capitalized or have a prefix global_

If we are talking about scripting: adding separate tests for each function is always helpful.