Table of Contents

Global and Local Symbol Assignment

For the non-programmer, especially, who is nevertheless writing a DCL command procedure (script), the notion of global vs. local symbols (variables) and symbol tables is at first a bit confusing. This article will hopefully make these concepts more clear.

First, the Practical Matter of Notation

Any DCL symbol (variable) is created (or defined) using one of the four following assignment operators: == or :==, = or :=. Note that the first two assignment operators each use two (double) equal-signs, while the second pair uses only single equal-signs.

These four operators, when spoken aloud, are rather clumsily pronounced: “equals-equals” or “colon-equals-equals”, “equals” or “colon-equals”.

Here are the rules for creating DCL symbols:

Two Forms of Assignment Operators

Okay… but why the two forms, like == and :==? Here, DCL's HELP command sheds some light (don't attempt to use $ HELP = or $ HELP :=, as these won't work because of command parsing limitations):

$ HELP

HELP

   The   HELP   command   invokes   the  HELP  Facility  to  display
   information about a command or topic.  In response to the "Topic?"
   prompt, you can:

      o Type  the  name of the command  or topic for which you need help.
...

  Additional information available:

  :=         =          @          ABS        ACCOUNTING ACL_Editor ...

Topic? =

=

     Defines a symbolic name for a character string or integer value.

     Format

       symbol-name =[=] expression
       ...

Topic? :=

:=

     Defines a symbolic name for a character string value.

     Format

       symbol-name :=[=] string
       ...

$

Read each of these HELP sections in their entirety. From this HELP text – rather quaint: “Defines a symbolic name…”, but we know that we're just creating variables here – we discover that:

Because of those side effects (also referred to as data “normalization”), experienced DCL script programmers usually avoid, or at least limit, their use of the :== and := assignment operators, because the == and = operators are more general purpose, and make obvious what the data-type of the value being assigned to a symbol actually is (this is a rule-of-thumb, not a hard-and-fast rule).

Next, Some Definitions

Demonstrating Command Procedure Depth

To best understand both global and local symbol tables, it helps to get a deeper understanding of how command procedure depth works; the following demo script can help you see the behavior of procedure depth and local symbol tables.

The following command procedure, RECURSE.COM, demonstrates this notion of depth. When invoked from the command line, this script then calls itself recursively three times; each invocation displays its view of both the process's global symbol table and it's own instance of the local symbol table:

$ ! RECURSE.COM -- a recursive-call com-file demo, showing procedure depth           !  1
$ !
$ procdepth = F$ENVIRONMENT( "DEPTH" )  ! capture procedure depth in local variable  !  3
$ !
$ wso = "WRITE sys$output"              ! define this local variable (symbol)        !  5
$ wso ""                                                                             !  6
$ !
$ wso "*** == Global Symbol Table (part), always at Procedure Depth 0 ***"           !  8
$ SHOW SYMBOL /GLOBAL $S*                                                            !  9
$ wso "###  = Local Symbol Table (entire) at Procedure Depth ''procdepth' ###"       ! 10
$ SHOW SYMBOL /LOCAL *                                                               ! 11
$ !
$ IF ( procdepth .LT. 3 )                                                            ! 13
$ THEN wso ""                                                                        ! 14
$      callnumber = procdepth + 1                                                    ! 15
$      wso ">>> Recursive call #", callnumber, ": @RECURSE ''callnumber'"            ! 16
$      @RECURSE 'callnumber' ! call self recursively, up to 3 times                  ! 17
$ ENDIF                                                                              ! 18
$ !
$ wso ">>> exiting from recursion #", procdepth                                      ! 20
$ EXIT 1                                                                             ! 21
$ !

Annotations:

And here's the output/trace from invoking RECURSE.COM, invoked with an illustrative command line parameter P1 – see the above annotations as you read through this output/trace:

$ @RECURSE "from com-line depth=0"

*** == Global Symbol Table (part), always at Procedure Depth 0 ***
  $SEVERITY == "1"
  $STATUS == "%X00010001"
###  = Local Symbol Table (entire) at Procedure Depth 1 ###
  P1 = "from com-line depth=0"
  P2 = ""
  P3 = ""
  P4 = ""
  P5 = ""
  P6 = ""
  P7 = ""
  P8 = ""
  PROCDEPTH = 1   Hex = 00000001  Octal = 00000000001
  WSO = "WRITE sys$output"

>>> Recursive call #2: @RECURSE 2

*** == Global Symbol Table (part), always at Procedure Depth 0 ***
  $SEVERITY == "1"
  $STATUS == "%X00010001"
###  = Local Symbol Table (entire) at Procedure Depth 2 ###
  P1 = "2"
  P2 = ""
  P3 = ""
  P4 = ""
  P5 = ""
  P6 = ""
  P7 = ""
  P8 = ""
  PROCDEPTH = 2   Hex = 00000002  Octal = 00000000002
  WSO = "WRITE sys$output"

>>> Recursive call #3: @RECURSE 3

*** == Global Symbol Table (part), always at Procedure Depth 0 ***
  $SEVERITY == "1"
  $STATUS == "%X00010001"
###  = Local Symbol Table (entire) at Procedure Depth 3 ###
  P1 = "3"
  P2 = ""
  P3 = ""
  P4 = ""
  P5 = ""
  P6 = ""
  P7 = ""
  P8 = ""
  PROCDEPTH = 3   Hex = 00000003  Octal = 00000000003
  WSO = "WRITE sys$output"
>>> exiting from recursion #3
>>> exiting from recursion #2
>>> exiting from recursion #1
$