The first WRITE is not unknown to Natural.
It defaults to the physically preceding GET.
Hence the output, and no 434.
Even if they were both READs, with both END-READs after the three WRITEs, there would be no 434. Natural would default to the innermost READ, which would be VIEW2, or FALSE.
However , still working with READs, if you put a non qualified TKS after the second end-read you would get a 434.
Fortunately, even though it is only 7am here, I get up at 5am and hence have had breakfast and three cups of coffee, so my brain was able to unravel what I think is where you may have gone wrong in your reasoning.
I think you have intermixed compile time with execution time in your reasoning. Here is your code:
GET VIEW1 171 /* TKS = TRUE
perform view2get
*
WRITE ’ TKS’ TKS /* no NAT0434 here /* physically preceding GET is VIEW1
WRITE ‘VIEW1.TKS’ VIEW1.TKS
WRITE ‘VIEW2.TKS’ VIEW2.TKS
*
define subroutine view2get
GET VIEW2 2 /* TKS = FALSE
WRITE ‘SUB TKS’ TKS /* no NAT0434 here /* physically preceding GET is VIEW2
end-subroutine
The WRITE after the PERFORM defaults to VIEW1 (physically preceding). At execution time, the preceding GET is indeed VIEW2. BUT, Natural had to decide at compile time which GET dictated the first of the three physically contiguous WRITEs. Hence the selection of VIEW1, not VIEW2.
There are other examples of physical appearance taking precedence over logically executed.
For example, Natural takes its column “layout” from the physically first DISPLAY statement in a program, EVEN IF, that DISPLAY is never executed.
Example:
:::
END-DEFINE
*
IF #A NE #A
DISPLAY NOHDR list of field names eg. #T1#T2#T3 …
END-IF
:::
READ…
IF some condition
WRITE T*#T2 NAME STATE
ELSE
WRITE T*#T3 NAME PROVINCE
END-IF
END-READ
The column layout is controlled by the physically first DISPLAY statement. It (first DISPLAY) serves the same role as a tabset on a typewriter.
define data local
1 view1 view of employees
2 name
1 view2 view of employees
2 name
end-define
*
** if you move subroutine definition here you will get NAT0434
*
get view1 1
write ‘=’ name ‘from view1’
**
** if you move subroutine definition here, you will get name from view1
*
get view2 2
write ‘=’ name ‘from view2’
perform mysub
*
define subroutine mysub
write ‘in mysub, name is’ name /* here you get name from view2
end-subroutine
*
end
So yes, you can alter the logic of the code by merely moving the subroutine. At least moving it to the top produces an error message; moving the subroutine between the two GETs produces different (erroneous?) output.