0

I run JMP 15.2.0 and my jsl script includes this section of code, which has a minor bug:

for each row(
    if (:ColumnA == 99, ColumnA = .)
);

The 2nd ColumnA should have a leading : in order to replace 99's with null. But for some reason this works, despite the bug, when run via JMP as a script, yet not when installed as an "Add-In".

Why would the exact same script work (i.e., 99's get nullified as intended) when run as a script, but not as an "Add-In" (99's remain and no error appears in the log)?

Shouldn't jsl be interpreted the same whether run through JMP as a script or as an "Add-In"? Could my JMP instance be somehow set to use different engines for different modes? Has anyone else observed this confounding JMP strangeness?

Woodchuck
  • 3,869
  • 2
  • 39
  • 70

2 Answers2

2

The reason this happens is due to how JMP handles scope. When you give an unscoped variable (is not of the form ns:var, :var, ::var), then JMP has a sequence to try to find the proper scope for the variable of interest. It goes something like this

  1. Check local namespace -- if found, done
  2. Check Current Data Table columns, if found, done
  3. Check here namespace -- if found, done
  4. Check global namespace -- if found, done

Since you did not define "Column A" anywhere in your script, the only valid name for which "Column A" applies is the column name.

Inside of a "For Each Row" statement the order is to check column names first (higher precedence than any other scope).

Update: Note that the above list is for explicitly unscoped variables without any 'unscoped variable handling' -- that is, no "Names Default to Here( 1 )" line. Note that if you have that line starting the script then it does not affect the data table, as the unscoped "ColumnA" variable only ever gets placed within the Here namespace. JMP doesn't do scope-walking to see if it can find a "ColumnA" variable in the various listed namespaces above.

I've included a picture of the most common way of attaching a script to an addin -- this is what I'm assuming you're doing. Notice that by default the line 'Use the "Here" namespace for unqualified JSL variable names' is checked -- unqualified means has no colon (unscoped). This check-box is forcing JMP to only look at Here:ColumnA when seeing the unscoped variable. You need to run the script without any automatic scope control to work as it does when run as a standalone.

Addin scripts by default link unscoped variables to the "Here" namespace, making it so that unscoped column names don't work

  • Does jmp handle scope differently when the jsl is run as a script compared to when run as an add-in? – Woodchuck Mar 01 '22 at 05:20
  • I've updated the post as a bit of an answer (so that I could include an image). The answer is -- yes, JMP does handle scope differently in an Addin -- at least by default. When putting a script linked to a menu entry (either by directly putting the script into the menu, or by linking to a file), JMP will by default have the option selected to automatically put unscoped variables into the Here namespace -- equivalent to running the script with "Names Default to Here( 1 );" as the first line. Note that if the script does have this first line then it does not have the strange behavior. – Jordan Pierce Mar 01 '22 at 08:14
  • Wow, this answer seems to explain it. I create add-ins by opening the jmpaddin file via "Open using Add-In Builder". I then compose the script from an editor that appears from there. That editor contains a checkbox to toggle "Use the 'Here' namespace for unqualified JSL variable names." Checking or unchecking that is in fact what makes the difference. Thanks much, @Jordan Pierce! – Woodchuck Mar 02 '22 at 22:21
0
Current data table(dt);
  
for each row(dt,
        if (: ColumnA == 99, :ColumnA = .););
Simanti
  • 26
  • 3
  • 2
    Thanks for the answer. I'm confident it works. But my question is why does my script (which contains a typo) work when run as a script, but not when installed as an "Add-In". – Woodchuck Aug 19 '21 at 05:00
  • 1
    When we open a script window it automatically recognizes the active/last data table, active in the window. Hence the piece of code identifies the column by name and acts accordingly. However, when the script is made into an add-in, it will require explicit mention of a data table (because it should work in generic fashion) and also requires specific notation for its column. This is what my understanding is. – Simanti Aug 20 '21 at 11:41
  • Hm, not sure I follow exactly. It's true I don't declare a data table before my "for each". But is the syntax I show for ColumnA (with no leading colon), ever correct. Is that leading colon optional or required? (Also, in your example, is the space after that colon intentional?) – Woodchuck Aug 22 '21 at 02:54