Subscribe Bookmark
melaniedrake

Staff

Joined:

May 30, 2014

5 reasons I love the new JSL Debugger

That’s right, JMP 10 ships with a brand new JSL Debugger. Say goodbye to the old and hello to the new! As I was wondering what I could say in a blog post about it, I started thinking about ways it makes my life as a JSL scripter easier. This post introduces a few wonderful features, and subsequent posts will zoom in on details.

The JSL Scripting Guide has a full description of the JSL Debugger, along with a few simple examples to get you started. In the meantime, here are some things to look forward to.

5. It Works!

That may be a bit harsh, but I found our previous JSL Debugger so limited in features and painful to use, I never used it. I now find myself abandoning my old habits of liberally sprinkling my code with Show()s, Print()s, and Write()s, and instead I turn to the new debugger. Which has the added benefit of not releasing my script to co-workers only to find I forgot to comment out or delete several Show()s.

JMP 9 Debugger

JMP 10 Debugger (Windows)

As an added bonus, you don’t have to add /*debug step*/ to the top of your script to debug it. You can click the Debug Script toolbar button ( Debug Script Button) for your script — it’s right next to the Run Script button. Or select Edit>Debug Script. Or right-click in the script window and select Debug Script. Or press CONTROL-SHIFT-R (COMMAND-SHIFT-R on Macintosh). Easy!

4. It’s Available on Macintosh, Too

JSL Debugger (Macintosh)

Oh, happy day! I can now debug JSL scripts on Macintosh as well as Windows! The debugger is the same one on both platforms. Same great features, same great functionality. I know my fellow Macintosh enthusiasts will welcome this, since the tired, old debugger wasn’t even available on Macintosh.

3. Debugging Loops and User-Written Functions

The days of selecting small pieces of code in your loops and running them piecemeal (while trying not to select the comma that resulted in a JSL error) are over. I can hear the cheers from here. As you run your code through the debugger, you can see the value of your iteration variable automatically updated each time it changes. You can use breakpoints to bypass the chunks you know are working. You can add a condition to a breakpoint and run through the first 200 iterations with one click, and then focus on where your trouble begins in the 201st iteration.

Debugging your functions is easier, too. You no longer have to separately declare whatever your “passed” variables are, and then run pieces of the function. You can just run the script to the function and step into it. The debugger shows you all values of the variables you pass in and the ones that are local to the function.

2. Stepping Into, Over, and Out of Code Blocks

Do you already know the expression you’re calling is flawless? Click Step Over in the debugger to run the expression with one click and stop at the next expression. Are you certain something is going wrong in your function? Click Step Into to enter the function and run each expression one at a time within the function. Are you halfway through stepping line by line through an Include() file and realize your problem isn’t here? Click Step Out to finish running the rest of the included script and return to debugging the expression that follows the Include().

1. Watching Variables

This was the one thing the old debugger did, but it was hard to use and limited. Variable-watching is a delight in the new debugger. The values of every single variable are shown in any scope that exists – global, local, here, namespaces. You don’t need to do a thing: It’s always there. As new variables are added in your code, they are added to the appropriate list. Add a new namespace, and a new list for it appears.

If you write lengthy scripts that use dozens of variables, those lists can get overwhelming. So flip over to the Watch tab.

  • You can add just the few variables you want to keep an eye on.
  • If you want to watch as values are added to a particular JSL list, you can subscript (for example, you can watch mylist).
  • You can scope in the watch list (for example, you can watch here:var and global:var at the same time).
  • You can type your variable name into the watch list, but it’s even easier to right-click on the variable name in the debugger’s script pane and select Add Watch.
  • Stay Tuned...

    Watch this space for more posts on the debugger, where I’ll discuss particular features and use cases in detail. Interested in a particular debugger topic? Mention it in the comments, and I’ll try to address it in a future post.

    6 Comments
    Community Member

    Lee Creighton wrote:

    I'd love a demo showing local variables in the debugger.

    Community Member

    Jenny M wrote:

    You rock Mel!

    Community Member

    Ben wrote:

    Quick question -- I run a bunch of scripts via the command line. JMP 8 or 9 introduced a new "feature" by which doing that causes the script to run -- but not appear. So, if a script that I launch via the command line barfs, will it show up now like it did in 6? In 9 I'm having problems like coming in in the morning to a JMP window stuck open with "N col(dtab) -- dtab is not a data table reference" and little idea which script invoked N col(dtab). I've tried adding "show("launching c:\ben's script.jsl")" but that NEVER seems to show up when this happens.

    Also, useful for debugging -- default settings when just running a script -- does JMP still spit out

    "Column not found in bad argument (x)"

    ?

    ('x' sometimes shows up as a number)

    Having something like

    "you asked for column 'Bens_column_name" out of table "Bens_target_data_table" in code line 1234 where you said 'eval(Bens_column_list_variable)' but there is no such column"

    is a much more useful error.

    Also, I don't think this is automatically fatal, and frequently not throwing an error for 'bad column' is problematic -- a 'catch' statement usually has to show up somewhere:

    plt = bivariate(x(:nonexistent_column), y(:nonexistent_column_2));

    plt << do something;

    if I want this to just skip over the bad columns, I'm going to need an

    IsScriptable(plt);

    anyway.

    Thanks.

    Melanie Drake wrote:

    Do you run your scripts one by one, launching JMP and quitting JMP for each, or do you launch JMP once and run your scripts as includes? In the first case, (one instance per script), the show() is appearing in the log for me. In the second, the container script quits JMP, so you never see anything. A colleague suggested using a log capture in each script and saving the log capture as a text file that you can look at later. I have alternate approach below.

    Error messages haven't changed much.

    I think if you send bad column references to a platform, your script fails right there, and you won't get to the Is Scriptable(plat). You might use a Try() to skip the whole thing if your column references are bad. For instance:

    Try( plt = bivariate(x(:nonexistent_column), y(:nonexistent_column_2));

    plt << do something;

    // do more stuff

    , // else if any of the above expressions fails, do this instead

    Save Text File("c:/error log.txt",

    "c:\ben's script.jsl: error in first bivariate case",

    mode("append")

    )

    );

    Note that you would have to create the text file first, before you can append to it. An approach like this might help mitigate your first problem as well.

    Thanks for your interesting questions!

    Community Member

    John Sall offers reflections on JMP 10 wrote:

    [...] investing in writing scripts, and JMP 10 has many new features to offer in that area. It has a new JSL Debugger, split-screen support for the JMP Log, drag-and-drop editing, improved add-in construction, and a [...]

    Community Member

    Dewey wrote:

    Ð xcellennt Ñ ost. I will be dealing with many of these

    issues as well..