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.