9 Replies Latest reply: Apr 19, 2012 12:03 PM by Brian.T.Tanner RSS

    [JS CS5.5] Complex Application, want context that current script was called from

    Brian.T.Tanner Community Member

      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.

        • 1. Re: [JS CS5.5] Complex Application, want context that current script was called from
          absqua Community Member

          There's method outlined in the Scripting Guide to get the current script while running in the ESTK, using error handling:

           

          function myGetScriptPath() {
            try {
              return app.activeScript;
            }
            catch(myError) {
              return File(myError.fileName);
            }
          }
          

           

          Jeff

          • 2. Re: [JS CS5.5] Complex Application, want context that current script was called from
            Brian.T.Tanner Community Member

            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()".

            • 3. Re: [JS CS5.5] Complex Application, want context that current script was called from
              absqua Community Member

              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?

              • 4. Re: [JS CS5.5] Complex Application, want context that current script was called from
                John Hawkinson CommunityMVP

                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.

                • 5. Re: [JS CS5.5] Complex Application, want context that current script was called from
                  Brian.T.Tanner Community Member

                  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?

                  • 6. Re: [JS CS5.5] Complex Application, want context that current script was called from
                    John Hawkinson CommunityMVP

                    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...

                    • 7. Re: [JS CS5.5] Complex Application, want context that current script was called from
                      Brian.T.Tanner Community Member

                      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.

                      • 8. Re: [JS CS5.5] Complex Application, want context that current script was called from
                        John Hawkinson CommunityMVP

                        #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...

                        • 9. Re: [JS CS5.5] Complex Application, want context that current script was called from
                          Brian.T.Tanner Community Member

                          In fact turning it off will even allow me to do the things I wanted in the first place.  So life is grand.  Thanks John!  I learned a lot through this little exchange!