6 Replies Latest reply on Aug 11, 2011 2:21 PM by John Hawkinson

    [JS][CS5] question, and comments

    Roy Marshall Level 1

      HI All.

       

      I must first start off by recommending anyone seriously wanting to get into Scripting, or (like me) am fairly knowledgable, but needed the resource, to check out "InDesign CS5 Automation Using XML & Javascript" by Grant Gamble. (Amazon, Kindle etc...)

       

      I am sure I am not the only one who has made his way, stumbling and even hacking through code to produce scripts that work well, but not really understanding why certain things were done in a certain way. This books helps a great deal with this, laying a good basis for further development.

       

      Anyway, on to my question. In the afore mentioned book, he talks about making a global variable/object that is used to pass variables into throughout the script ie:

       

      var g = {};

      main();

      g = null;

       

      function main(){

      //code here

      //g.win = new Window("dialog",undefined,"New Window");

      //etc.....

      }

       

      I can see how this works, with "g" being a master item, but why would this be needed? It seems more confusing to me, but maybe cause I am self taught, and not really been shown the "proper" way to use variables!

       

      Can someone explain the reason behind this for me.

       

      Many Thanks

       

      Roy

        • 1. Re: [JS][CS5] question, and comments
          [Jongware] Most Valuable Participant

          The ONLY variable that 's ever "used" in this script is g. All other variables are either local (because defined inside a function) or, when a global one is needed, defined 'inside' g.

           

          By ensuring g is null right before you exit, you prevent polluting the memory and/or data leaks out of the script into the global memory pool.

          • 2. Re: [JS][CS5] question, and comments
            Roy Marshall Level 1

            Thanks Jongware.

             

            So is this normal practice? 

             

            Can I then use this 'g' variable to store ANY type of variable? Arrays, strings, etc...

             

            Cheers

             

            Roy

            • 3. Re: [JS][CS5] question, and comments
              [Jongware] Most Valuable Participant

              Roy Marshall wrote:

               

              So is this normal practice?   Can I then use this 'g' variable to store ANY type of variable? Arrays, strings, etc...

               

              Normal? It's sort of anally retentive, IMO ...

              Can you story anything? Yeah, sure, Javasccipt allows that. But if you are in doubt of its usefulness ... don't use it.

               

              It's perfectly possible to write all of scripts with all of your variables global, and without using a function 'main'. The name of this function suggests a similar usage as in the C programming language, but it could be named 'whatever_you_want' -- it's not part of the language specification.

               

              The same goes for global variables. Use them at will, I'd say, until you run into any side effects (not really likely) or learn to program cleanly (not really necessary, as I can attest ), or learn to be Paranoid and don't want anyone else snooping in the insides of What You Were Doing In That Script.

               

              My conviction is there is nothing wrong when starting to program to use global variables. Only when you learn to use functions, you're going to appreciate the details of global vs. local variables (and then usually after making a number of silly mistakes in this regard).

              • 4. Re: [JS][CS5] question, and comments
                John Hawkinson Level 5

                Err. Jongware said:

                The ONLY variable that 's ever "used" in this script is g. All other variables are either local (because defined inside a function) or, when a global one is needed, defined 'inside' g.

                No, in Javascript functions are variables too. This script modifies the global namespace in two ways: g, and main.

                That's not really good practice.

                 

                By ensuring g is null right before you exit, you prevent polluting the memory and/or data leaks out of the script into the global memory pool.

                Umm, no you don't. This is bad!

                 

                Global variables should be avoided where possible. They may be necessary sometimes, but if you initialize a variable and then set it to null

                afterwards, then it never needed to exist. Can it.

                 

                And setting a variable to null does not mean it can be garbage-collected. I suppose it is a way to prevent a data leak, but it is a horrible way. Javascript has closures (variables scoped to functions). Use them!

                 

                 

                Normal? It's sort of anally retentive, IMO ...

                 

                That almost implies its good. It's not.

                 

                What is similar to this is the design pattern that if you have to use global variables, you should use one and only one global variable. Make it an object and put everything you might need globally inside it. That way you only pollute the global namespace in one way.

                 

                In this case, the code should be written as:

                 

                (function () {
                  var g = {};
                  g.win = new Window("dialog",undefined,"New Window");
                })();
                

                 

                No globals. But if for some reason you needed a global for persistent state, then:

                 

                var ROYMARSHALL = ROYMARSHALL || {};
                (function () {
                  ROYMARSHALL.gwin = new Window("dialog", undefined, "New Window");
                })();
                

                 

                For throwaway scripts we often skip using anonymous functions because they are hard for beginners to read, and since #targetengine main resets and throws away all state anyhow, it doesn't matter too much.

                 

                p.s.: Roy, how can you recommend a book when you don't know why it makes these recommendations, and indeed the recommendations seem a bit questionable? That's an awfully odd basis for a recommendation!

                • 5. Re: [JS][CS5] question, and comments
                  Roy Marshall Level 1

                  Thanks guys.

                  It is good to see a difference of opinion, this sort of enforces that there may be no true and only way, as long as code problems are minimised, and things work as they intended, all is good.

                   

                  On your point John, Obviously you put yourself at a level greater than someone needing this book, but I know my short comings, and can see HUGE value in a book detailing why certain practices are carried out, rather than copying forum posts and maybe not understanding the whys and wherefores behind the solution.  The point I raise in only a small part of the book that I have not understood up to now, and the fact that folks like Jongware dont simply dismiss it, to me means it is a valid practice.  I know I can carry on in the way I was before, and probably will, but I have the mind that needs to know "WHY"

                   

                  Thanks again for the input,

                   

                  Roy

                  • 6. Re: [JS][CS5] question, and comments
                    John Hawkinson Level 5

                    Hi, Roy:

                     

                       I'm going to try again.

                     

                        Don't fool yourself. A difference of opinion doesn't mean both sides are right. It could well mean one side is wrong. (Maybe that's me. Maybe that's Jongware. Let's wait and see what he has to say.)

                     

                        In this case...this design pattern is just dumb. Unless there's something you're not showing us, like multiple functions that need to exchange data...in which case there is probably a better way, but it's hard to evaluate.

                     

                        The pattern is dumb because it does bad things with no upside. It makes the code harder to read. It adds potential conflicts with other scripts. And it has no benefit.

                     

                        I should probably have given you yet another example of something better. The very simple one. It's not as good because it still pollutes the namespace with main, but it's easy to understand and to read:

                     

                    main();
                    
                    function main() {
                       var g = {};
                       g.win = new Window("dialog", undefined, "New Window");
                    }
                    

                     

                    Even ignorance of a fnuction is probably better, since you could wrap it in a function later on (as your program got more complex) and it would all still work. That is:

                     

                    var g = {};
                    g.win = new Window("dialog", undefined, "New Window");
                    

                     

                    But I suspect you're oversimplifying the program, since you told us that the point of this "technique" was to "pass variables into throughout the script."

                    But your example doesn't demonstrate any "passing." It's not too clear exactly what you mean though.

                    But here are some examples:

                     

                    var g = {};
                    f1();
                    f2();
                    
                    function f1() {
                      g.able = "baker";
                    }
                    function f2() {
                      alert(g.able);
                    }
                    

                     

                    There we have some data moving from f1() to f2(). But it's still poor. You should write it like this:

                     

                    main();
                    
                    function f1() {  return "baker";
                    }
                    function f2(s) {
                      alert(s);
                    }
                    function main() {
                      var tmp;
                      tmp = f1();
                      f2(tmp);
                    }
                    

                     

                    But if for some reason it was really complicated and you needed to have f1() and f2() messing around directly with the data, then you could have a variable that was scoped to both of them:

                     

                    function main() {
                      var shared;
                      function f1() {
                        shared = "baker";
                      }
                      function f2() {
                        alert(shared);
                      }
                    
                      f1();
                      f2();
                    }
                    
                    main();
                    

                     

                    But still you would never set a variable to null when you were done. The language has much better features than that! Use them!

                    When the enclosing function exits, there's never any fear of anything else gaining access to the variable. No need to set its value, because nothing can access it! Cross the final } and you're set. Awesome!

                     

                     

                    Obviously you put yourself at a level greater than someone needing this book, but I know my short comings, and can see HUGE value in a book detailing why certain practices are carried out

                    Respectfully, this is not a reasonable answer.

                     

                    There are a lot of books out there. That you have found one that is better than forum posts does not mean it is a good idea to recommend it, especially when it seems to have problems. If you've read through several books and found this one to be better than the others, then that might be a good basis to recommend it. Or if you have searched high and low for books and failed to find any. Or if you were comparing it to Adobe's documentation on scripting. But by all means, do tell us the standard of comparison you're using...

                     

                    But it doesn't sound like you're doing that. It sounds like you're in one breath praising a book, without comparing it to anything else. And in the next breath, you're asking a question (rightly so!) about what appears to be a bad practice that is advocated by the book.

                     

                    That just doesn't make much sense.

                     

                    I hope I'm misinterpretting you.