[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] Scoping question



At 12.38 -0400 1999.07.20, gibson wrote:
>>>   # if we pass to here, the XML file is fine.  now parse to create a
>>>   # list of subjects in the file.
>>>   $nSubjects = 0;
>>>
>>>   $p3 = new XML::Parser(Handlers => {Start => \&hStartCnt});
><SNIP>
>>Not a global variable.  A lexical variable is not global.  Access to it is
>>limited to the lexical scope.  In this case, the lexical scope is the file
>>(or if all of this code is in a block, then the lexical scope if the whole
>>block).
>
>Just to clarify terminology, MPPE (as you know ;-) states that:
>
>"Any variables created (or used) within a Perl program, which are not
>explicitly made private, are global; that is, they (and their current
>values)
>are available to your entire program, including subroutines. "

I kinda misstated in my post; I was thinking that you had somewhere before
declared the variable as lexical.  I read this:

>Since in both cases $nSubjects is defined outside the block of the
>subroutine, it would seem that it should be treated as a global variable
>(this is my understanding after reading MPPE).  Why is this not true?

WHERE something is declared does not relate to what it is.  If declared
with my() it is lexical, else it is global.


>As I read the subsequent material, a variable is made private using the
>"my" keyword, so in my script, $nSubjects should be "global" in the sense
>referred to in the quote.

It should be global in every sense of the word (as perl knows it). There is
only one sense of the word in Perl: something that is global can be
accessed from anywhere.


>I can only interpret "global" in the sense of
>lexical scoping, where the current code block is the whole file, and the
>whole file knows the value of $nSubjects.  Correct?

No.  Something that is lexically scoped is not global.  Something that is
global is not lexically scoped.  If the whole file can see the lexical
variable, then it is not global, it is called a file-scoped lexical.  But
other files cannot see it, so it is not global.

The bottom line is that your variable (if you don't use my() on it) is
global, and it is available from anywhere in your program.  If you do use
my() on it, it is lexical, and can only be accessed from within a certain
lexical scope.

There is another type of scoping, unrelated, called dynamic scoping.  In
theory, any variable can have dynamic scope, though right now only global
variables can have dynamic scope.  Dynamic scope is "when", whereas lexical
scope is "where".  In lexical scope, you need to access the variable within
the block of code that the variable was declared in.

In dynamic scope (which is in some cases done for you, such as with for()
loops, and in some cases done explicitly, with local()), the specific value
of a given variable is available only while the current block is being
executed.

  $x = 1;

  print $x;    # 1 (main value of global $x)
  &foo;        # 1 (main value of global $x)

  {
    print $x;  # 1 (main value of global $x)
    &foo;      # 1 (main value of global $x)
    local $x = 2;
    print $x;  # 2 (new dynamically scoped value of global $x)
    &foo;      # 2 (dynamic scope still in effect for global $x, even in &foo)
  }

  print $x;    # 1 (main value of global $x)
  &foo;        # 1 (main value of global $x)

  {
    print $x;  # 1 (main value of global $x)
    &foo;      # 1 (main value of global $x)
    my $x = 3;
    print $x;  # 3 (new lexical variable $x, not same variable as global $x)
    &foo;      # 1 (main value of global $x)
  }

  print $x;    # 1 (main value of global $x)
  &foo;        # 1 (main value of global $x)

  sub foo {print $x}  # global variable $x

Here, local() affects the global variable $x and gives a value for it that
runs out when its dynamic scope ends.  my() creates a new lexical variable,
which is unrelated to the global variable $x, so when &foo is called, it
does not see the lexical $x and accesses the global $x.


>Duh.  Still on the Perl learning curve, I got so worried about scope,
>variable declarations, etc. I forgot the simple, no-brainer issues.
>Sorry for the stupid question.

No worries.

--
Chris Nandor          mailto:pudge@pobox.com         http://pudge.net/
%PGPKey = ('B76E72AD', [1024, '0824090B CE73CA10  1FF77F13 8180B6B6'])

===== Want to unsubscribe from this list?
===== Send mail with body "unsubscribe" to macperl-request@macperl.org