[oak perl] still clueless about "my"

Belden Lyman blyman at iii.com
Fri Feb 4 09:34:16 PST 2005


Hi Sandy,

On Fri, 2005-02-04 at 04:25, Sandy Santra wrote:

> But you know, I'm still clueless about using the "my" operator
> for purposes of scoping.  I've studied the definition and
> the examples and it's all very confusing. 
> 
> *Your* example makes total sense:
> 
> >
> >   foreach my $file ( glob '*' ) {
> >       my $newfile = $file ;
> >   }
> 

My guess is this makes sense to you because you understand
the "lifespans" of $file and $newfile within your code. You
know where the variables need to exist, and know when the
code no longer needs them.


> because you put the "my" definition within the If statement.
>  But so often in code I see quoted, the "my" statement is
> put at the very beginning of the quoted code, before the
> "if" (or sub or while or whatever) statement even starts--so
> how can that "my" delcaration scope to something?

It's possible that you've come across some bad code examples-
many people, when told to use strict and warnings, "fix" the
'Global symbol' errors by just putting a huge variable
declaration at the top of their program.

It's also possible that you've come across some code which is
doing some tricky things.


>   Here's an example: 
> 
> my $princess = "I dream of Jill.";
> if ($princess =~ /ill\b/) {
> 	print "Jill might be ill.\n";
> }
> 
> Now what if this If statement was followed by 6 other If
> statements...  Does some sort of invisible tether link the
> "my" declaration in the beginning to *only* the very first
> If statement? 
> 

Nope. $princess is available to all the other code within the
same scope as $princess.

This sounds like a circular definition, so I'll explain a little.

Say your program looks like this:

         1	#!/usr/bin/perl
         2	
         3	use strict;
         4	use warnings;
         5	
         6	my $princess = 'I dream of Jill.';
         7	
         8	if ( $princess =~ /ill\b/ ) {
         9	    might_be_ill();
        10	}
        11	
        12	if ( $princess =~ /ream/ ) {
        13	    say_ice_cream( $princess );
        14	}
        15	
        16	sub might_be_ill {
        17	    print "entered might_be_ill()\n";
        18	    print "$princess\n";
        19	    print "Oh no! She might be ill!\n\n";
        20	}
        21	
        22	sub say_ice_cream {
        23	    my $p = shift @_;
        24	    print "entered say_ice_cream()\n";
        25	    print "\$p        is $p\n";
        26	    print "\$princess is $princess\n";
        27	    print "did you say ice cream?\n" ;
        28	}
        29      __END__

                entered might_be_ill()
                I dream of Jill.
                Oh no! She might be ill!
    
                entered say_ice_cream()
                $p        is I dream of Jill.
                $princess is I dream of Jill.
                did you say ice cream?

Notice that even though $princess isn't passed in to might_be_ill(),
that subroutine is still able to see $princess. Play around with
might_be_ill() - change $princess and see what happens.

And notice also that say_ice_cream() has a private copy of $princess,
but is still able to access $princess.

Think of '{' as saying, "I am the start of a new scope". And
think of '}' as saying, "I am the end of the scope." When you
create a 'my'-ed variable, then it can be seen by any code that
gets run afterwards in the same scope.

   {
      # perl code here
   }

is often referred to as a BLOCK - you'll see this in 'perldoc
perlfunc'.

Knowing this, you can re-write the above code to make $princess
available only to the first IF block. Change lines 6 through 10
to look like this:

    {   # start a new scope

      my $princess = 'I dream of Jill.' ;

      if ( $princess =~ /ill\b/ ) {
         might_be_ill() ;
      }

    }   # end the scope - $princess disappears

and then run the program again. You'll get scoping errors,
since we try to use $princess outside its scope.

> Here's another example:
> 
> my $bedrock = 42;
> $bedrock++;
> 
> How and what is the "my" declaration scoping in this example?
>  (This one makes me want to tear my hair out.)  If this
> piece of code was dropped into a huge piece of code, I don't
> understand how it would scope the definition of $bedrock
> to anything. 

$bedrock will be limited to the BLOCK of code it's scoped to.
If you see a '{' and '}' before and after $bedrock, then chances
are good that those define its scope.

I say "chances are good" because there are some exceptions.
For example, these things *look* like code blocks, but are
not.

     $var =~ s{foo}{bar}g ;       # same as $var =~ s/foo/bar/g
     $var =~ m{foo} ;             # same as $var =~ /foo/ ;
     $var = q{hello world};       # $var = 'hello world';
     $var = qq{hello world\n};    # $var = "hello world\n";
     @ary = qw{hello world};      # @ary = split /\s/, 'hello world';

On the other hand, you might be dealing with a variable like in
the $princess example above- one which is effectively scoped to
everything that gets run after the declaration.

> 
> This "my" scoping confusion I have is frustrating because
> I know that scoping is very important.  "my" is used in
> almost every piece of code I read in Perl forums and instruction
> manuals.  But half the time the "my" declaration is in the
> middle of nowhere, and I can't fathom why it's there or
> what it's affecting.  Boy, I need help with this. 
> 

For more than you want to know about scoping, check out
MJD's "coping with scoping" article on http://perl.plover.com
at http://perl.plover.com/FAQs/Namespaces.html Some of this will
go over your head, but it's worth trying to understand. Re-read
that article in 6 months: it'll make more sense.

Belden



More information about the Oakland mailing list