How to avoid running code when a script is imported as a package?
This works on my Windows machine (not sure how well it translates to Mac and Linux yet):
Place this in a file called test.wls
:
checks = { $Notebooks, Length[$CommandLine]===1, MemberQ[$CommandLine,"-wlbanner"], MemberQ[$CommandLine,"-noicon"] };
Print @ Switch[
checks,
{True,False,False,True}, "Running in notebook interface",
{False,True,False,False}, "Running in wolfram.exe",
{False,False,True,False}, "Running in wolframscript.exe",
{False,False,False,False}, "Running in test.wls"
];
Then run this file in different modes. First as a script:
C:\Users\arnoudb.WRI>test.wls
Running in test.wls
Then using wolframscript.exe
:
C:\Users\arnoudb.WRI>wolframscript
Wolfram Language 11.3.0 Engine for Microsoft Windows (64-bit)
Copyright 1988-2018 Wolfram Research, Inc.
In[1]:= Get["test.wls"]
Running in wolframscript.exe
Then using wolfram.exe
:
C:\Users\arnoudb.WRI>"C:\Program Files\Wolfram Research\Mathematica\11.3\wolfram.exe"
Mathematica 11.3.0 Kernel for Microsoft Windows (64-bit)
Copyright 1988-2018 Wolfram Research, Inc.
In[1]:= Get["test.wls"]
Running in wolfram.exe
And finally from a notebook interface:
Get["C:\\Users\\arnoudb.WRI\\test.wls"]
Running in notebook interface
Probably needs some work to get this more solid.
You may be able to use $EvaluationEnvironment
to check notebooks vs. Scripts.
If you are trying to check against whether it is the main file or not $Input
may be useful. It should be set when Get
-ing a file or similar. So the check If[$Input==="", ...]
may work for you.
The way that works is that when Python runs a source file as the main program, it first sets the variable __name__
to "__main__"
(see this answer). As far as I know, Mathematica does no such thing for you, so unless you want to require every source file to include code to replicate that behavior, the closest I can think of is to have the script check if it is being evaluated as part of a Get
or Needs
expression. Something like:
If[
MatchQ[Stack[], {___, Get|Needs, If, MatchQ}],
Print["this will evaluate if being imported by Get or Needs"],
Print["this will evaluate otherwise"]
]
That being said, I wouldn't really recommend writing code like this and would rethink if this behavior is really necessary.