• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

ESTK Data Browser Question

Community Expert ,
Nov 11, 2016 Nov 11, 2016

Copy link to clipboard

Copied

Does anyone know if the scope of the data browser (while stepping through the code) is customizable at all?

By default, it shows the local scope, showing only the variables local to the current function. Is it possible to include inherited variables in the display?

Specifically i'm trying to view some JSON of script global scope in the data browser so I can just peruse all the properties rather than writing a loop to display certain props.

Thanks in advance,

William.

TOPICS
Scripting

Views

2.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Valorous Hero , Dec 29, 2016 Dec 29, 2016

URGENT update! Extra Extra! Stop what you're doing and read all about it!

So, after all of these years, I clicked on something by accident today which revealed the very simple yet to me undiscovered feature of the ESTK: I clicked inside of the "Call Stack" panel. What it does is act like a shortcut between all the scopes that are you your current execution happening. I'm attaching some screenshots, you can see that I am using a breakpoint to pause inside of a double-click event inside of a functi

...

Votes

Translate

Translate
Adobe
Valorous Hero ,
Nov 11, 2016 Nov 11, 2016

Copy link to clipboard

Copied

One way to look into them could be to add a testing container variable object to the global object so that you can view in any function scope.

2016-11-11 09_56_15-_ Source1.png

2016-11-11 09_56_04-.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

Here is a 2cts thought:

var api = (function () {

  var obj;

  return {

  init:function() {

  var doc;

  if ( !app.documents.length ) {

  return false;

  }

  doc =app.activeDocument;

  obj = {

  doc:doc,

  height:Math.round(doc.height*100)/100,

  width:Math.round(doc.width*100)/100

  }

  return true;

  },

  run:function() {

  if ( !app.documents.length || !obj.doc ) return;

  alert( obj.doc.name +" measures "+obj.width+" x "+obj.height );

  }

  }

})();

if ( api.init() ) {

  api.run();

}

else {

  alert("You need an open doc");

}

FWIW

Loic

Ozalto | Productivity Oriented - Loïc Aigon

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

Hmmm.. Thanks for the replies guys.. But i'm having trouble wrapping my head around both of those.

Silly,

In your example, would i have to duplicate every variable i want to be able to view globally? In other words. Whenever i initialize a local variable, i also then have to apply that variable to "all_my_test_vars" as well? This seems like a lot of extra work and clutter in my scripts. Plus i don't necessarily want everything all the time. But I want to have access to some things (ever changing based on what's currently failing) whenever i need them.. It doesn't seem prudent to double up my code everywhere (or else spend time guessing what parts are most likely to have issues later) on the off chance that I'll need to look at that specific thing.

Loic,

I'll gladly admit to my ignorance and inexperience here. I have no idea what's going on in your example. I see that it's taking an object oriented approach and using methods rather than using linear function calls as I normally would. But I wouldn't even know where to start integrating that into my existing code. And even if i did, I can't picture how it would change my data browser situation.

For further clarification, here's what I'm trying to do.. I'll run a function to compile data necessary to complete a future function and return the data in JSON format. Then I pass that JSON into another function. Occasionally, that function will fail, usually due to some undefined variable or unexpected value. At that point, it's hard to trace the issue back to it's origination because the only error i get is "undefined is not an object" or "numeric value expected". But I can't look at all the properties of the object I passed in because it came from a higher scope and the data browser only shows the scope of the current function. So what I always end up needing to do is write some kind of for in loop to display all the properties of the object so i can find out which value is incorrect and then work backwards till i discover what went wrong while trying to set that value. Here's a brief simplified example:

var globalObject = function getData()

{

     var obj = {};

     //code to determine whether to scale something

     obj.scale = [boolean];

     obj.width = (something).width;

     obj.height = (something).height;

     //code to determine distance between 2 objects or otherwise positional relationship

     obj.rel = [some value]

     return obj;

}

function futureFunction(globalObject)

{

   

I'm going to stop right here because as per usual, in trying to explain my problem, i've answered my own question. I guess i have not been actually passing the object itself as an argument, but rather simply trying to access the values from inside the function like so:

function futureFunction()

{

     var ratio = globalObject.width / globalObject.height;

     return ratio;

}

ratio may fail or be undefined if either height or width was undefined, but the values for globalObject will not display in the data browser because it's not in the local scope. But in testing this while writing this response.. i see that if you pass the whole object as an argument to the function it does show up as expected in the data browser

Thanks for letting me talk myself through this "issue".

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

You are not that far

var globalObject = (function getData()

{

     var obj = {};

     //code to determine whether to scale something

     obj.scale = [boolean];

     obj.width = (something).width;

     obj.height = (something).height;

     //code to determine distance between 2 objects or otherwise positional relationship

     obj.rel = [some value]

     return obj;

})(); //executing function on declaration

Then globalObject.width should be ok.

Loic

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

That makes sense. However the issue i typically have is that when i'm buried several levels deep in function calls within function calls within function calls, then i have trouble finding out exactly what the problem is. I tend to create "global" objects (script global, but still wrapped in a container function to keep true global variables out of ESTK) so they'll be accessible from many different functions at different levels.

It's pretty rare that i'll only need the data within a single specific function. In your example if I added a new function below the declaration of globalObject, the key value pairs of globalObject still wouldn't show up in the data browser unless i pass globalObject as an argument to the function. Like this:

var globalObject = (function getData()

{

     var obj = {};

     //code to determine whether to scale something

     obj.scale = [boolean];

     obj.width = (something).width;

     obj.height = (something).height;

     //code to determine distance between 2 objects or otherwise positional relationship

     obj.rel = [some value]

     return obj;

})(); //executing function on declaration

function newFunction()

{

     //since i didn't pass globalObject as an argument, it doesn't show up in the data browser while i'm stepping through this function.

}

So all i need to do is this:

function newFunction(globalObject)

{

     //now, if i set a breakpoint inside this function, i can browse globalObject in the data browser and quickly identify whether the values are correct without writing a loop in the console to display the properties and values

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

In my example, you would only do this to the variables you'd like to 'watch' so they appear in the data browser in any scope - since they get attached to the 'this [global Object]'.

In your case since you only want to watch the 'globalObject' variable, you can attach it that way and watch it later in the data browser when you're inside one of your functions.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

Understood Silly. However, I never know which variables i'd like to watch until something breaks. Ultimately if I had the foresight to know what's likely to break or why it might break, I'd simply fortify that part of the code so i'd be reasonably sure it WOULDN'T break at all or at least alert me in a helpful way. The problem comes in after i've already written the code and i get an error that doesn't produce a helpful error message. And the problem is that by the time the error happened, I'm already outside the scope of the problem area and thus i don't know where it failed originally until i work my way back through to find out when or why the error occurred.

Admittedly, this is simply a function of poor logging and/or error handling and simply not taking the time up front to identify potential pitfalls and handling those issues from the getgo.

But I've built up quite a codebase already and i simply don't have the time at the moment to go back through and rewrite everything or add in correct error handling for all possible errors. So I'm stuck trying to work with a "when i get an error, investigate and fix that specific error" kind of mentality. =(

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

[bad advice] While the best way would be to begin anew, as I have had to do plenty of times, the next-best thing to do in these cases is to use the technique not unlike my example wherein you stick a 'running' variable stating what the problem is into a global variable for the purpose of alerting it when an error comes, or seeing it in the data browser.

You can attach an object to 'this' and in your functions you can then update it to log the function you are currently inside of, the specific blocks, etc. Peppering your code with such unique messages would be a quick and dirty, rudimentary way of adding some more awareness to your existing code.

For example:

#target illustrator

function test(){

  try {

     this.problem = "";

     function myFunc_1(){

          problem = "Now running myFunc_1";

          if( app.documents[0].name == "Dude!" ){

               problem = "if-statement inside myFunc_1";

               return true;

          }

          return false;

     }

     function myFunc_2(){

          var res = myFunc_1();

          problem = "Now running myFunc_2";

          if( res ){

               problem = "if-statement inside myFunc_2";

               return ("Success!");

          } else {

            problem = "if-statement inside myFunc_2 was false";

              return "Meh...";

          }

     }

     var msg = myFunc_2();

     alert(msg);

     } catch (e) {

      alert(this.problem);

     }

};

test();

In this example, in myFunc_1 there is a condition which will throw an error because when you don't have a document open, it will neither return true nor false from myFunc_1, but will stop right there when it throws an error.

This is easily caught when running from ESTK, but in other cases where the error comes from other sources it may not be so apparent. As you can always see the 'this.problem' variable in the global object, you can stick this as part of an alert message to at least give you a hint of where you're at. I took a step of wrapping this snippet in a try-catch for quicker run-through. This is just basically a glorified alert-box tracing.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

I do use a similar method to figure out problems. I use a try/catch block that alerts "e" as well as a customized error message like "Failed while setting the positional relationship between and ."

But if the failure happens because a value was improperly set 2 or 3 function calls back, this method breaks down because it only tells me "things aren't working right now" it doesn't let me see why things aren't working, especially because the error "undefined is not an object" can refer to an unset variable OR an item in the document that doesn't exist.

So when i use a try/catch statement to display errors like this, I have to decide how frequently to use them. Because if i have a few statements inside a try block, there are multiple possibilities for failure that will all return the same error message. Example:

try

{

     var blah = something.prop;

     var blahBlah = app.activeDocument.layers[0].groupItems["someGroup"].duplicate();

}

catch(e)

{

     alert(e); //in this case, e will  be "undefined is not an object" regardless of which of the above lines of code fails.

     alert("either something.prop doesn't exist or there is no groupItem named someGroup");

}

So this brings me back to my point above regarding how frequently i utilize try/catch statements. Do i wrap each variable definition in a try/catch? (what a mess that code would be!).

What I was getting at in my initial post was if the code fails, i'd like to set a breakpoint in the function where the error occurred and then explore the values that I'm trying to access to determine whether "something.prop == undefined" or whether the group item "someGroup" doesn't exist. Which is fine. That part is easy. but what if something.prop was generated over the course of the last 3 functions? I need to know where that process broke down.

So again. It goes back to poor handling of errors to begin with. I allowed errors to go through silently. I know the correct way to handle those errors (now) and to ensure those errors don't occur in the first place, but i've got 10's of thousands of lines of code written and constant demands for new code and infrastructure projects, so i just don't have the time to go back and add in all of those things. All of my new code handles these issues properly so it's not a problem going forward, but what i'm left with is, how do i quickly find the origination of such errors in legacy code? And at this point, it's looking like either using the console and for in loops to read key value pairs or else pass the entire object to the function as an argument so it shows up in the data browser.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

Oh, yea, I see what you mean now. Well there's no way around it - some code has to be re-written, it's a fact of life and they should provide you with the time and funding for the proper effort. At this time, if the best you can do is trace to where the script fails and then spend a bunch of time working back over the previous 3 functions to see what happened, that's part of the work and it is what it is.

However, if you are talking about using for-in loops or being able to pass objects into functions, it tells me that you probably have several such objects that you are aware of and where they're at and what they do - so if you attach them to the 'this global object' and update them, you can see them in the data browser in all the scopes without having to do extra tracing code.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2016 Nov 22, 2016

Copy link to clipboard

Copied

yea. i think i see where you're going with that. I'll try it out.

Thanks Vasily. 😃

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 29, 2016 Dec 29, 2016

Copy link to clipboard

Copied

URGENT update! Extra Extra! Stop what you're doing and read all about it!

So, after all of these years, I clicked on something by accident today which revealed the very simple yet to me undiscovered feature of the ESTK: I clicked inside of the "Call Stack" panel. What it does is act like a shortcut between all the scopes that are you your current execution happening. I'm attaching some screenshots, you can see that I am using a breakpoint to pause inside of a double-click event inside of a function called "UIWindow()". Inside the event function's scope there's only a "this", which is the object listBox, but when I click on the name "UIWindow()", it shows that parent scope and what's happening in it at the given time.

Also, quite conveniently, I can see that debugging works with multiple files and you can set a breakpoint inside of one of your open files which are #included in the file you're running, and the ESTK will jump between the files showing you the line of focus.

Having 'discovered' this, I can only imagine the hours of debugging time I could have saved over the last several years! Gasp!

Screen Shot 2016-12-30 at 1.10.28 AM.png

Screen Shot 2016-12-30 at 1.09.34 AM.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 30, 2016 Dec 30, 2016

Copy link to clipboard

Copied

yea.. that's pretty cool but..

it's only EXACTLY what i was looking for!

Yet again you prove your wizard status, my friend. Thanks so much. this will be life changing!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 30, 2016 Dec 30, 2016

Copy link to clipboard

Copied

If wizard status is bumbling around like a headless chicken, then I want my award, please!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 30, 2016 Dec 30, 2016

Copy link to clipboard

Copied

at least you find answers at the end of your bumbling. my bumbling seems to go on ceaselessly.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 03, 2017 Jan 03, 2017

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 03, 2017 Jan 03, 2017

Copy link to clipboard

Copied

side note here, but ...

Did you know you could customize the ESTK?!   Look inside the ESTK app package and you'll see piles of JSX scripts. It runs on JSX!  Here is oldie but goodie post from the InDesign forums where Bob Stucky demonstrates a custom tool written for the ESTK:

multiple .jsx to .jsxbin

In case any of you AI script writers are interested... you can get crazy and write a tool to help write a tool.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 04, 2017 Jan 04, 2017

Copy link to clipboard

Copied

See here too:

ExtendScript Toolkit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 04, 2017 Jan 04, 2017

Copy link to clipboard

Copied

thanks for sharing, haven't seen dirk's repository before.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 05, 2017 Jan 05, 2017

Copy link to clipboard

Copied

LATEST

Dirk is more into InDesign but I thought his ESTK scripts were worth being mentioned here.

loic

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines