Check something only once on function call

I have a nice function

const MUSESCORE = @static Sys.iswindows() ? "MuseScore" : "musescore"

function test_musescore()
    r = try
        r = run(`$(MUSESCORE) -v`)
    catch
        false
    end
    if r == false || ((typeof(r) == Base.Process) && r.exitcode != 0)
        throw(SystemError(
        """
        The command `$(MUSESCORE) -v` did not run, which probably means that
        MuseScore is not accessible from the command line. Please first install MuseScore
        on your computer and then add it to your PATH."""
        ))
    end
end

inside a julia package. This function is called later on to confirm that another function can actually run, e.g.

function musescore(file, notes; display = true, grid = nothing)

    test_musescore()
    # do stuff ...
end

Now here is my question:

I want to be able to run test_musescore() only once from within musescore per new session a user starts. Is this possible? Because I think try blocks are slow, if one wants to do “Batch conversions” that may be bad for performance. So how can this be done in a performant way? via a global variable?

Not really answering your question directly, but is trying the command the only way to figure out if it’s there? I’m not familiar with Windows command line stuff, but with Unix you could do something like which musescore which would return a blank line if the program isn’t in the $PATH, or return the path if it is.

I’m not sure best practices with global variables, but I often make a const FLAGS = Dict{Symbol,Bool}(). I haven’t benchmarked anything, but it seems fine (prsumably the type of anything pulled from the dict can be known, but the dict itself is mutable so I can change or add flags).

To be honest I am totally clueless about how to check whether something is on the command line :smiley: so if anyone has a better suggestion please be my guest.

The dictionary suggestion seems okay. I also am not sure about the performance due to the global nature but maybe it is not that bad in the end. Most of the time will be spent out of Julia anyway.

See if which works:

$ which musescore
$ which python
/usr/local/bin/python

So you could just check if the return has length 0. Again, this is unix, not sure about windows equivalent.

As to the Dict, I remember reading that using const helps with the performance of global stuff because the compiler knows it can’t change. Again, I haven’t interrogated this extensively and might be misremembering.

which doesn’t exist on windows, yes. So I am looking for a platform independent way of checking this…