In raw, unmitigated Perl, variables are global in scope. That is, they exist in your program from where you define them to the end of the script. Also, in Perl, variables spring into existence when you use them with an undefined value. In strings, this is treated as a null string. In numbers, it's treated as a zero.
Thus, in a subroutine, if you defined a variable in your main program, it's defined in your subroutine:
$foo = "Hello";
call_sub();
sub call_sub {
print "$foo\n";
}
That will print "Hello".
However, no one should ever use Perl in this mode because it's so easy to have errors:
$name = "Bob"
print "Hello $Name!\n";
Whoops! I used $name
when I defined it, and $Name
when I used it. Plus, you don't want such global variables. Otherwise, your subroutines may overwrite your main program variables. Makes it really, really hard to write large complex programs.
In order to get around this, you are highly encouraged to put these two lines in your code:
use strict;
use warnings;
The use warnings;
will issue a wide variety of warnings such as uninitialzed variables being treated as strings and numbers.
The use strict;
makes even a bigger change. To put it simply (and incorrectly), use strict
forces you to declare your variables before you can use them.
use warnings;
use strict;
my $name = "Bob"
print "Hello $Name\n";
This program won't work because $Name
was never declared (you declare variables with the my
keyword). You can see how that will prevent errors.
However, declaring these types of variables are known as lexically scoped variables. That is, they can go in and out of existence. If a variable is defined in a block, it will be undefined once outside of a block. Think of a block as the curly braces:
Subroutines are a block
sub foo { # Curly brace starts the block
...
} # Curly brace ends the block
This means if you define a variable in a subroutine, it's only in that subroutine.
Also, while
and for
loops are blocks:
for my $foo ( @foo_list ) { # The variable $foo is only defined in this loop
...
} # End of block and end of loop
while ( my $foo = <@foo_list> ) { # Again, $foo is only in this block
...
} # End of the block
if ( $foo == $bar ) { # Another block
my $foo = 1; # $foo is defined in the block
} # $foo is no longer defined
You can even use just curly braces:
my $foo = 1;
print "$foo\n" # Prints 1
{
my $foo = 2; # Redefines $foo it's a different $foo!
print "$foo\n" # Prints 2
} # End of block, $foo in block is now out of scope
print "$foo\n"; # Prints 1 because the original $foo is in scope.
Let's look at this:
my $foo = 2;
my $bar = 5;
print "$foo\n"; # Prints 2
call_sub(5); # Prints "Foo is 5!"
print $foo\n"; # Prints 2
sub call_sub {
my $foo = shift; # Different $foo from main program!
print "Foo is $foo!\n";
print "Bar is $bar\n"; # Will print "Bar is 5" because $bar is in scope
} # Subroutine's $foo falls out of scope
As you can see, $bar
was defined before I called the subroutine and so it's defined in the subroutine and still in scope. However, The $foo
in my subroutine was redeclared, and remains until the end of the subroutine and falls out of scope. Thus, my subroutine's use of $foo
won't interfere with my main program.
So, in answer to your question:
- Always use
use strict;
. This will force you to declare variables before they can be used.
- Variables are not defined until declared with
my
.
- Variables can have a limited scope where they live and breath. This can be very useful. Don't sit there and declare all variables at the beginning of your program with
my
like you would do in Pascal. Declare them where they are used, and let them fall out of scope when they're not needed.
- Subroutine variables are not private because a Subroutine can use an already declared variable. This is a bad idea because it allows a subroutine to override the value of a variable in your main program. So, always declare all of your subroutine variables with
my
to be safe.
- Use
use warnings;
to warn you when you forgot to define a variable you're trying to use.
And finally, I lied, but for a very good reason. Variables in Perl are a wee bit (a lot) more complex than I presented. You have the concept of name space, package variables, and a way to localize variables are aren't even local. Even people who work with Perl for years have a hard time understanding the ramifications.
use strict;
doesn't really force you to declare variables. It forces you to either use lexically scoped variables which you declare with my
or use fully qualified variable names for package variables (or use our
to declare those).
However, in the end, use strict;
does in a way force you to declare a variable since 99% of the variables you will use in Perl will be declared with my
. When you learn more about Perl, you can learn a bit more about that other 1%.
For more information, take a look at PerlSub about using my
for private variables, and the take a look at PerlMod for a full discussion about package variables, using local, and (how could I forget!) the newly introduced state variables.