Question
· 14 hr ago

Subscript indirection behaves differently in if statement

Hello Community,

When I run the following code with x undefined in terminal, it throws a syntax error and returns control to the program stack. After issuing a GO command, execution continues, and setting the global variable ^zz1.

code 1:

test.mac
if $Data(@x@(a,b,c)) {
    set ^zz1=1212
}
write !,1212,!
//
//or
if $Data(@x@(a,b,c)) set ^zz1=1212
write !,1212,!

 if I assign the result of $D(@x@(a,b,c)) to a local variable like d using set d=$D(@x@(a,b,c)), and then use if d { ... }, the code fails(global is not set) working as expected.

Code 2

test1.mac
set d=$D(@x@(a,b,c))
 if d {
     set ^zz1=1212
 }
 write !,1212,!
 ;
 if d set ^zz1=1212
 q

So, Why The body of the if statement is not tied to the success and it sets the global in the code 1.

Thanks!

Product version: IRIS 2024.1
$ZV: IRIS for Windows (x86-64) 2024.1.1 (Build 347U) Thu Jul 18 2024 17:40:10 EDT
Discussion (7)1
Log in or sign up to continue

I think you are leaving out some important information: you have a terminal session, but you are calling either a routine (.mac) or a (class) method, since a standard terminal session does not accept multi-lines (as you wrote above).
And when you call a routine or method, it would be nice to see that function/method. By the way, for indirection to work, you need variables with global visibility. So I'm assuming you're mixing some existing variables from your terminal session with variables from your routine/method.

I modified the post slightly. I ran a routine via the terminal, and as expected, it threw a <SYNTAX> error because the variable x is undefined. Then I continued the program, and now both the single-line if statement and the block if statement (with braces) set all the global variable. I thought that block of code wouldn’t be executed

 if $D(@x@(a,b,c)) s ^zz1=1,^x=1,^y=2,^xx=1
 ;
 ;
 if $D(@x@(a,b,c)) {
     set ^zz1=1212
     set ^dd=1
     set ^fg=2
 }

I keep on nagging...
I expected to see the environment of your IF-line: is it in a block structure or not. Which variables are initialized, etc. But you always give me the same expressiveness information: just the IF-Statement.

Nevertheless, I think, I know, why you get the <SYNTAX> error:

- under "default conditions", executing the following lines gives you an <UNDEFINED> error

  kill
  set a=1,b=2   // x is not defined
  if $d(@x@(a,b))

- but the very same lines gives you a <SYNTAX> error if the setting, how undefined variables should be handled is set to 1 or 2 (I suppose, in your case it is set to 2) because x as nullstring is not a valid variable or global name.


To see the setting in question, go to:
ManagementPortal-->SystemAdministration-->AdditionalSettings-->Compatibility and look for the setting "Undefined". I'm pretty sure, there is a 2 (or maybe 1). The default setting is 0.

Hint: the above mentioned setting is a per job setting, you must start a new job to have the new setting in effect

If you have set the "handling of undefined" settings to 2 then in either case (you set x to a nullstring OR x is undefined) in statements like

if $d(@x@(whatever))
set d=$d(@x@(whatever))

you get a <SYNTAX> error, because nullstring (the value of x) is not a valid name for a local or global variable.

In a terminal session issue the following commands and check each output with mine:

kill         // kill all local variables
write x=""   // the output is 1 (because of your setting)
if $d(@x)    // the output is a <SYNTAX> because "" is not a valid name
set d=$d(@x) // the output is a <SYNATX> because "" not a valid name

If your output is different from the above, than please contact the WRC
My $ZV is IRIS for UNIX (Ubuntu Server LTS for x86-64) 2021.2 (Build 649U) Thu Jan 20 2022 08:49:51 EST

You are using GOTO after an error in programmer mode while debugging. After an error that stops execution the GOTO will just go to the next command. I haven't re-created what you did. My guess is that the existing value of $TEST is 1 (true) and is unaltered by the IF command that failed which means that the interpreter is happy that the next command is SET command. Ensure you define variable x with something sensible and/or write some code to check its value before using it. Alternatively, nest the whole thing in a TRY:CATCH construct to deal with the error.