Within a Julia script, can you tell whether the script has been imported or executed directly?
Asked Answered
A

5

31

A common convention in python is to structure the main functionality of a script as follows, so it can be both run as a script directly or imported without executing main() at the time of import:

def main():
    do_stuff()

if __name__ == '__main__':
    main()

Is there a similar variable that gets set in Julia, so that the script can be aware of whether it was imported using require("script.jl") or executed directly?

For example, say I have two scripts, a.jl and b.jl, along with a magic_function() that behaves as follows:

a.jl:

println("Did we execute a.jl directly? ", magic_function())

b.jl:

require("a.jl")

Executing the following commands results in ...

> julia a.jl
Did we execute a.jl directly? true
> julia b.jl
Did we execute a.jl directly? false

Does a function like magic_function() exist in the current distribution of Julia?

Aetolia answered 22/1, 2013 at 15:51 Comment(0)
S
12

Official Julia doc suggests this:

if abspath(PROGRAM_FILE) == @__FILE__

    # do something only this file is executed. 
    do_something()

end

The do_something function is only executed when the code is executed, not when the code is imported from other codes.

Ref:"How do I check if the current file is being run as the main script?" https://docs.julialang.org/en/v1/manual/faq/#How-do-I-check-if-the-current-file-is-being-run-as-the-main-script?-1

Shizukoshizuoka answered 9/8, 2017 at 20:10 Comment(3)
Not quite. PROGRAM_FILE is "" at the default REPL, and all strings contain "". There may be other path-based false-positives, too.Ridenhour
This doesn’t work: when I run ./script.jl, @__FILE__ is /home/me/script.jl and PROGRAM_FILE is ./script.jl. The latter is not contained in the former, so the condition is false. @oyd11’s solution above always works.Swill
In its current form and as of 2020-2021, I think this should be the accepted answerCrymotherapy
F
8

While isinteractive() will let you discern the REPL from being run on the commandline/imported into other code, there is no way to get exactly the same functionality as Python's if __name__ == '__main__'.

This does not seem to be planned as a feature. See this discussion on the mailing list. (from June 2013)

Fellmonger answered 27/11, 2013 at 2:4 Comment(0)
H
8

This is the best solution I have found:

module mymod
    # stuff here
end

if length(ARGS)>0 && ARGS[1] == "--run"
    using mymod
    mymod.myfunction()
end

Then you can import the module as normal, but you can invoke the executable like behaviour from the command line like this:

julia mycode.jl --run

The if statement could even be shortened to this if you have no other arguments to pass to the script:

if ARGS == ["--run"]
    # etc...
end
Honestly answered 10/11, 2015 at 14:29 Comment(1)
What if I write a script abc.jl that imports your mycode.jl and do julia abc.jl, then your your mycode.jl will still think it's being run directly, which is not true. If so, then your answer is not equivalent to Python's approach.Deportee
A
6

I use

if ""!=PROGRAM_FILE && realpath(@__FILE__) == realpath(PROGRAM_FILE)

I've seem a similar solution was voted down above, I'd like to know what's wrong with that, I'm using this both for a few unit-tests and some modules that are also commandline chmod 755 utils

(just added the ""!=PROGRAM_FILE for the 'REPL include' case, becoming a bit of a mouthful)

Agustinaah answered 20/6, 2018 at 9:50 Comment(0)
K
3

You want the isinteractive() function. Try it out in the REPL, the compare its result with the result of calling it from a script like in this BASH one-liner: julia -e "println(isinteractive())".

Kipton answered 22/1, 2013 at 20:34 Comment(2)
Is that the same thing, though? julia test.jl where the script is simply println(isinteractive()) will print false, whereas python test.py / print __name__ == '__main__' will print True.Ivied
This isn't quite what I need: isinteractive() tests whether it's executed from the REPL or from running julia my_script.jl, not I ran julia my_script.jl or julia script_that_requires_my_script.jl. Updating the question for clarity.Aetolia

© 2022 - 2024 — McMap. All rights reserved.