I'm trying to create a slightly sophisticated application that is spread across several script files. Some functions in these files call either other. Here is what I want to emulate:
A.jsx
--------
if(mainScript=="A.jsx"){
doA();
}
function A(){}
B.jsx
---------
#include A.jsx
if(mainScript=="B.jsx"){
doB();
}
function B(){
// some stuff
A();
//some more stuff
}
C.jsx
#include A.jsx
#include B.jsx
#include D.jsx
main(){
D();
A();
etc...
}
Basically, I want a script to act differently depending on if it is the one being called or if it is being called from elsewhere. I thought I could do this pretty easily by using global variables and something like:
if(mainScript==undefined){
var mainScript=$.fileName;
}
But global variables persist between script calls so this doesn't work. I'm a bit stuck. Anyone know how to do this? app.activeScript doesn't work because I am executing through the extendScript toolkit.
I'm vexed.
This seems to just provide the name of the file where that function is defined or where myError is generated. What I am trying to determine is: what was the *first* or *main* script that was run, and is the current script file that one?
Not sure if it'll help, but I know in Python they do something like:
if __name__ == "__main__":
main()
And this basically says "if this is the main file that was executed, and not one that was just included by someone else, call main()".
I'm sorry—I shouldn't have chimed in without really trying to understand what you're doing. (I still haven't, honestly—sorry, no time.) I think includes are treated as if you copy/pasted them at the #include line in the including file. I don't think you'll have any information about context other than the script file name. Maybe pass the first script name as an argument and then pass it along to every subsequently called function, comparing it to the active script name in each one?
Brian, this is just not a good pattern to use.
The answer is easy: don't do it this way. Design .jsxinc files to be included by .jsx files, don't include .jsx files inside other .jsx files. Make each file either a file that is included, or one that performs inclusion, but not both.
This makes the code easy to read and meets most requirements. What are you trying to accomplish that does not fit that paradigm?
Even if you could find a way to make what you wanted work, it would be hard and confusing to read, and tough for others to maintain.
You're definitely not wrong John, this will resolve the problem. Sometimes, especially when doing development in a large project with lots of interlocking pieces it's convenient to be able to have some test code within each file that tests the functionality of that specific code. Even moreso when you are new to a language, so when you think you find a better way to do something you can quicky try it out and see what happens without invoking your monolithic program. It's not difficult to achieve this approach by splitting into two files, it just means that you have to keep twice as many file tabs open and remember which one to switch to "Go" instead of doing it with the code you are working on. It seems like an extra step for no good reason.
I do this in Java all the time, most of my complex classes have a main() method so they can be executed standalone to try out a quick snippet or test some corner cases. Comprehensive unit testing would probably be better but the time investment is much greater plus I doubt something like that would be well supported with ExtendScript.
Is there any different between a jsx and jsxinc file or is that just a common naming convention that you or a community of people use to differentiate files?
Yeah, I think it just not a pattern that works well in Javascript. (I appreciate what you mean about Java).
I suppose I would try a testA() function the A.jsx file, etc., and adjust the main program to call testA() instead of doA().
Or if you have A.jsx, B.jsx, C.jsx, and main.jsx, instead of modifying main.jsx (undesirable) or creating seperate testA.jsx, testB.jsx, and testC.jsx, just add a test.jsx that includes A, B, and C and then calls testA(), etc. That way you don't double the number of files, you just add one (scales better).
Is there any different between a jsx and jsxinc file or is that just a common naming convention that you or a community of people use to differentiate files?
It is Adobe's naming convention for ExtendScript, and of course its optional. But naming a file .jsxinc does help to encourage the belief that you ought not try to execute it directly...
At the risk of actually being helpful, I'm puzzled why your global variables are persisting, unless you are running in a persistent scripting engine...
John Hawkinson wrote:
At the risk of actually being helpful, I'm puzzled why your global variables are persisting, unless you are running in a persistent scripting engine...
<Shrug>
I open the ExtendScript Toolkit and press the play button. Looks like based on whatever book/tutorial I originally started reading when making this code I also seem to have put the following at the top of my files. Not sure if they are doing anything ![]()
#targetengine "session"
#strict on
I'm not as hacky of a developer as it sounds (I promise), I just had a lot to learn and so when I got a basic environment working I kept going. One day I should go re-read the scripting guide, I'd probably learn a lot.
#targetengine "session"
#strict on
Yes, these cause your script to run in a persistent engine called "session" which means global variables will persist (so you need to be a *lot* more careful with them), and also windows and hooks and eventListeners can persist after the script execution appears to complete.
If you do not require these things, then removing the targetengine line may be a good idea.
But on the other hand, the discipline you get from persistent global vars should be good for you. But probably not good enough to outweigh the problems you're going to have...
North America
Europe, Middle East and Africa
Asia Pacific