Global data types issue with Arrays?


    Apr 17 2006 | 4:31 pm
    Hopefully there is a very quick answer to this issue, either yes or no...
    I'm having a lot of trouble setting/retrieving information from a Global variable. Specifically, adding string or object properties to a Global seems to work just fine, but for some reason I can't attach an Array and make it stick. The following code demonstrates this - I create a Global object ( asGlobal = new Global("AuthoringSystem") ) and then attach an Object to it (SurfaceManager) and attach the property "className" to that, and assign that a string value. All is good, I can print that to the Max window. But after creating an Array (asGlobal.SurfaceManager._surfaces), the Array becomes undefined after the function that created it is finished. So I'm confused, perhaps I'm making some very dumb mistake (always possible), or is there an issue with attaching Arrays to Global variables and then reading them back?
    Code attached below, on Max 4.5.7 on OS X 10.4.6.
    Thanks, Evan
    /****************** Begin JS file ****************/ var debug = true;
    // class for managing Surface data objects storage and retrieval function SurfaceManager() { //internal representation of global SurfaceManager this.sm = null;
    asGlobal = new Global("AuthoringSystem");
    if (!asGlobal.SurfaceManager) { if (debug) post("Creating new SurfaceManagern");
    asGlobal.SurfaceManager = new Object(); this.sm = asGlobal.SurfaceManager;
    // here's where the problem is - need to attach an Array to Global asGlobal.SurfaceManager // put some data in just for testing, otherwise this should be "new Array()" this.sm._surfaces = new Array("poop", "cats");
    this.sm.className = "SurfaceManager";
    //debugging post (asGlobal.SurfaceManager._surfaces[0] + "n");
    }
    addSurface = function (s) { // this prints out correctly if (debug) post("ClassName : " + this.sm.className + "n"); //this will cause an error showing that _surfaces is undefined, for some reason, but shouldn't be. if (debug) post(this.sm._surfaces[0]);
    this.sm._surfaces.push(s); } }
    // wrapper for SurfaceManager's addSurface() function addSurface() { var args = new Array();
    for (var n = 0; n < arguments.length; n++) { args.push(arguments[n]); }
    sm.addSurface(args); }
    // in case we need to re-initialize Global vars (say, for testing) function init() { var smg = new Global("AuthoringSystem"); smg.SurfaceManager = null; sm = new SurfaceManager(); }

    • Apr 17 2006 | 7:58 pm
      So to clarify my question (slightly), the problem isn't the Global object itself, but in me trying to create an array that is a property of an object, inside a class. That sounds convoluted, so what I mean is I have class SurfaceManager-->Object sm-->Array surfaces. No good - the Object named sm is fine, as is any other first-level property, but its sm->Array property called "surfaces" disappears after the constructor is called.
      So, there's a good reason why I'd want to create an Object that has properties in the Global object - to use it as a namespace, so I can register classes and store data in it for further use. But if I just create a Global and assign a lot of properties to it, what if I wanted to clear them out later? It would be a lot easier for me to add/remove single Objects to a main Global object, each one containing the bunches of properties that I want to make accessible to the rest of the code.
      Does that make sense? You can certainly do this in Actionscript, and Java, but is this a Javascript limitation or a Max js bug? Do I need to create an entirely new class for each second-level Object?
      thanks, evan
    • Apr 19 2006 | 10:03 am
      Hmm... looks like no one knows the answer to this? (queue crickets chirping on the javascript-dev list)
      I changed my code to get around it (have to finish this on time), but I'm curious if I've overstepped the bounds of js with this one, or if I'm simply doing this the hard/wrong way for js.
      thanks, evan
    • Apr 19 2006 | 5:46 pm
      Probably the delay in answer is that your code is somewhat complicated (and actually confusingly organized with redundant namings of variables and classes). At least that's why I didn't take the time to go through it. I'd recommend asking these questions in general terms (rather than w/r/t surface managers, subclasses, etc. which don't have to do with the question at hand), or al least strip it down to something someone can glance at quickly and answer your problem. It appears to me that you may be confused w/r/t object oriented programming in JS and/or variable scope.
      The following code works for me, calling test set and testgrab from two different instances of js, demonstrating that this is possible with the global object, but note the subtle distinction in object scope and how you can't simply reference the object set to your global repository from any js instance. You need to do it through the global mechanism.
      var myrepository = new Global("my_global_repository"); var extref;
      function testset() { extref = new Object(); myrepository.charlie = extref; myrepository.charlie.s = "foo"; myrepository.charlie.a = new Array("poop", "cats"); }
      function testgrab() { // this should work from any instance myrepository.charlie.a.push("another");
      // this will *only* work from the js instance which called testset() // since otherwise "extref" is undefined. perhaps this is your error extref.a.push("and another");
      post(myrepository.charlie + "n"); post(myrepository.charlie.s + "n"); post(myrepository.charlie.a + "n"); }
      Let me know if you have problems with the above and don't feel that it's an adequate demonstration of your problem.
      -Joshua