Re: NCL variable scope

From: David Brown <dbrown_at_nyahnyahspammersnyahnyah>
Date: Tue May 17 2011 - 18:53:19 MDT

Hi Oli,
I am responding inline to your questions below:

On May 13, 2011, at 6:39 AM, <Oliver.Fuhrer@meteoswiss.ch> <Oliver.Fuhrer@meteoswiss.ch> wrote:

> Dear NCL team,
>
> I have a question about variable scope and good programming practice in
> NCL. The following code...
>
> ;=== BEGIN ===
> undef("gugus")
> procedure gugus( x:numeric )
> begin
> a = x
> end
>
> a = 1
>
> print(a)
> gugus(2)
> print(a)
> ;=== END ===
>
> ...outputs two times "1". So the scope of a in the procedure gugus seems
> to be local. Moving the declaration of a before the declaration of
> gugus...
>
> ;=== BEGIN ===
> a = 1
>
> undef("gugus")
> procedure gugus( x:numeric )
> begin
> a = x
> end
>
> print(a)
> gugus(2)
> print(a)
> ;=== END ===
>
> ...outputs "1" and then "2", so the scope of a in the procedure gugus
> now seems to be global, since the symbol is known when the procedure
> definition is encountered. Adding a "local a" statement to the procedure
> definition will again give two times "1" in the output. My questions are
> the following...
>
> - Is that the intended behaviour of NCL? Forgetting to declare variable
> as local can have quite dramatic consequences which depend on what code
> has been executed before the procedure call (i.e. has a already been
> used and defined or not).

The most definitive statement about NCL scoping rules is found in the
reference manual at
http://www.ncl.ucar.edu/Document/Manuals/Ref_Manual/NclStatements.shtml#Scoping

There is nothing in this description that in my mind contradicts the
behavior demonstrated above, and so yes this is the documented,
intended current behavior of NCL. However, although I have
only superficial knowledge of Pascal and I could be wrong
about this, I think that the statement that "The scope rules for
NCL are identical to Pascal." is a bit misleading. A situation like
your first example could not occur in Pascal because Pascal
requires global variable declarations (with specification of
variable type) prior to function and procedure declarations. So,
at least within the same file, all global variables are known to
all functions and procedures. NCL is like Pascal if you remove
the requirement for declaring variables with a specific type prior
to initialization and allow initialization anywhere.

>
> - Say I want to write a library "utilities.ncl" of NCL scripts which use
> a global variable "gDebug = True/False" to control verbose debugging
> output of the library procedures. It is probably good NCL programming
> practice to put all of these global variables at the beginning of
> "utilities.ncl" in such a way...
>
> undef("gDebug")
> gDebug = False
>
> ...in order to define the globals and inititalize them with default
> values. A NCL script can then load "utilities.ncl" and redefined gDebug
> = True as needed. Is there any standard practice to check wether the
> symbol gDebug is already in use and issue a warning upon the load
> "utilities.ncl" that there is a name conflict?
>
I don't think a standard practice for this situation has been defined,
but it would be possible to write something like

if (isvar("gDebug")) then
   ; issue warning
else
    gDebug = False
end if

I'm not sure if that really solves your problem though.

> - I am assuming that all procedure/function arguments in NCL are
> automatically "local" by definition, correct? For example, the program
> below correctly gives two times "4" for x.
>
> ;=== BEGIN ===
> a = 1
> x = 4
>
> undef("gugus")
> procedure gugus( x:numeric )
> begin
> a = x
> x = 3
> end
>
> print((/a,x/))
> gugus(2)
> print((/a,x/))
> ;=== END ===

Yes, that is correct. Arguments are always local.

We do know that the current local/global system has a number of
undesirable features, and that in retrospect, everyone on the current
development team agrees that it would have been much better if all
otherwise undeclared variables in a function or procedure were treated
as "local", and variables would only be global if they were listed in
a "global" statement.
We are in fact thinking about how we could introduce this behavior in
a backwards-compatible fashion. This would involve some
way of setting an option that would make local the default, plus a
new "global" keyword. Let us know if you have other suggestions.
 -dave

>
> Thanks and kind regards,
> Oli
>
> ________________________________________
>
> Oliver Fuhrer
> Numerical Models
>
> Federal Departement of Home Affairs FDHA
> Federal Office of Meteorology and Climatology MeteoSwiss
>
> Kraehbuehlstrasse 58, P.O. Box 514, CH-8044 Zurich, Switzerland
>
> Tel. +41 44 256 93 59
> Fax +41 44 256 92 78
> oliver.fuhrer@meteoswiss.ch
> www.meteoswiss.ch - First-hand information
>
> _______________________________________________
> ncl-talk mailing list
> List instructions, subscriber options, unsubscribe:
> http://mailman.ucar.edu/mailman/listinfo/ncl-talk

_______________________________________________
ncl-talk mailing list
List instructions, subscriber options, unsubscribe:
http://mailman.ucar.edu/mailman/listinfo/ncl-talk
Received on Tue May 17 18:53:28 2011

This archive was generated by hypermail 2.1.8 : Wed May 25 2011 - 09:35:33 MDT