Related
Before I start, the whole 'concept' may be technically impossible; hopefully someone will have more knowledge about such things, and advise me.
With Perl, you can "declare" global variables at the start of a script via my / our thus:
my ($a,$b,$c ..)
That's fine with a few unique variables. But I am using about 50 of them ... and the same names (not values) are used by five scripts. Rather than having to place huge my( ...) blocks at the start of each file, I'm wondering if there is a way to create them in one script. Note: Declare the namespace, not their values.
I have tried placing them all in a single file, with the shebang at the top, and a 1 at the bottom, and then tried "require", "use" and "do" to load them in. But - at certain times -the script complains it cannot find the global package name. (Maybe the "paths.pl" is setting up the global space relative to itself - which cannot be 'seen' by the other scripts)
Looking on Google, somebody suggested setting variables in the second file, and still setting the my in the calling script ... but that is defeating the object of what I'm trying to do, which is simply declare the name space once, and setting the values in another script
** So far, it seems if I go from a link in an HTML page to a perl script, the above method works. But when I call a script via XHTMLRequest using a similar setup, it cannot find the $a, $b, $c etc within the "paths" script
HTML
<form method="post" action="/cgi-bin/track/script1.pl>
<input type="submit" value="send"></form>
Perl: (script1.pl)
#shebang
require "./paths.pl"
$a=1;
$b="test";
print "content-type: text/html\n\n";
print "$a $b";
Paths.pl
our($a,
$b,
$c ...
)1;
Seems to work OK, with no errors. But ...
# Shebang
require "./paths.pl"
XHTMLREQUEST script1.pl
Now it complains it cannot find $a or $b etc as an "explicit package" for "script1.pl"
Am I moving into the territory of "modules" - of which I know little. Please bear in mind, I am NOT declaring values within the linked file, but rather setting up the 'global space' so that they can be used by all scripts which declare their own values.
(On a tangent, I thought - in the past - a file in the same directory could be accessed as "paths.pl" -but it won't accept that, and it insists on "./" Maybe this is part of the problem. I have tried absolute and relative paths too, from "url/cgi-bin/track/" to "/cgi-bin/track" but can't seem to get that to work either)
I'm fairly certain it's finding the paths file as I placed a "my value" before the require, and set a string within paths, and it was able to print it out.
First, lexical (my) variables only exist in their scope. A file is a scope, so they only exist in their file. You are now trying to work around that, and when you find yourself fighting the language that way, you should realize that you are doing it wrong.
You should move away from declaring all variables in one go at the top of a program. Declare them near the scope you want to use them, and declare them in the smallest scope possible.
You say that you want to "Set up a global space", so I think you might misunderstand something. If you want to declare a lexical variable in some scope, you just do it. You don't have to do anything else to make that possible.
Instead of this:
my( $foo, $bar, $baz );
$foo = 5;
sub do_it { $bar = 9; ... }
while( ... ) { $baz = 6; ... }
Declare the variable just where you want them:
my $foo = 5;
sub do_it { my $bar = 9; ... }
while( ... ) { my $baz = 6; ... }
Every lexical variable should exist in the smallest scope that can tolerate it. That way nothing else can mess with it and it doesn't retain values from previous operations when it shouldn't. That's the point of them, after all.
When you declare them to be file scoped, then don't declare them in the scope that uses them, you might have two unrelated uses of the same name conflicting with each other. One of the main benefits of lexical variables is that you don't have to know the names of any other variables in scope or in the program:
my( $foo, ... );
while( ... ) {
$foo = ...;
do_something();
...
}
sub do_something {
$foo = ...;
}
Are those uses of $foo in the while and the sub the same, or do they accidentally have the same name? That's a cruel question to leave up to the maintenance program.
If they are the same thing, make the subroutine get its value from its argument list instead. You can use the same names, but since each scope has it's own lexical variables, they don't interfere with each other:
while( ... ) {
my $foo = ...;
do_something($foo);
...
}
sub do_something {
my( $foo ) = #_;
}
See also:
How to share/export a global variable between two different perl scripts?
You say you aren't doing what I'm about to explain, but other people may want to do something similar to share values. Since you are sharing the same variable names across programs, I suspect that this is actually what it going on, though.
In that case, there are many modules on CPAN that can do that job. What you choose depends on what sort of stuff you are trying to share between programs. I have a chapter in Mastering Perl all about it.
You might be able to get away with something like this, where one module defines all the values and makes them available for export:
# in Local/Config.pm
package Local::Config;
use Exporter qw(import);
our #EXPORT = qw( $foo $bar );
our $foo = 'Some value';
our $bar = 'Different value';
1;
To use this, merely load it with use. It will automatically import the variables that you put in #EXPORT:
# in some program
use Local::Config;
We cover lots of this sort of stuff in Intermediate Perl.
What you want to do here is a form of boilerplate management. Shoving variable declarations into a module or class file. This is a laudable goal. In fact you should shove as much boilerplate into that other module as possible. It makes it far easier to keep consistent behavior across the many scripts in a project. However shoving variables in there will not be as easy as you think.
First of all, $a and $b are special variables reserved for use in sort blocks so they never have to be declared. So using them here will not validate your test. require always searches for the file in #INC. See perlfunc require.
To declare a variable it has to be done at compile time. our, my, and state all operate at compile time and legalize a symbol in a lexical scope. Since a module is a scope, and require and do both create a scope for that file, there is no way to have our (let alone my and state) reach back to a parent scope to declare a symbol.
This leaves you with two options. Export package globals back to the calling script or munge the script with a source filter. Both of these will give you heartburn. Remember that it has to be done at compile time.
In the interest of computer science, here's how you would do it (but don't do it).
#boilerplate.pm
use strict;
use vars qw/$foo $bar/;
1;
__END__
#script.pl
use strict;
use boilerplate;
$foo = "foo here";
use vars is how you declare package globals when strict is in effect. Package globals are unscoped ("global") so it doesn't matter what scope or file they're declared in. (NB: our does not create a global like my creates a lexical. our creates a lexical alias to a global, thus exposing whatever is there.) Notice that boilerplate.pm has no package declaration. It will inherit whatever called it which is what you want.
The second way using source filters is devious. You create a module that rewrites the source code of your script on the fly. See Filter::Simple and perlfilter for more information. This only works on real scripts, not perl -e ....
#boilerplate.pm
package boilerplate;
use strict; use diagnostics;
use Filter::Simple;
my $injection = '
our ($foo, $bar);
my ($baz);
';
FILTER { s/__FILTER__/$injection/; }
__END__
#script.pl
use strict; use diagnostics;
use boilerplate;
__FILTER__
$foo = "foo here";
You can make any number of filtering tokens or scenarios for code substitution. e.g. use boilerplate qw/D2_loadout/;
These are the only ways to do it with standard Perl. There are modules that let you meddle with calling scopes through various B modules but you're on your own there. Thanks for the question!
HTH
Suppose I have a function foo (or ::foo, or main::foo if you prefer), and I define
use strict;
my $sub_name = 'foo';
I want to invoke foo indirectly, as "the function whose name is stored in $sub_name". (For the sake of this example, assume that the invocation should pass the list 1, 2, 3 as arguments.)
I know that there's a way to do this by working with the symbol table for main:: directly, treating it like a hash-like data structure.
This symbol-table incantation is what I'm looking for.
I've done this sort of thing many times before, but I have not programmed Perl in many years, and I no longer remember the incantation.
(I'd prefer to do this without having to resort to no strict, but no biggie if that's not possible.)
I'd simply use a symbolic reference.
my $sub = \&$qualified_sub_name; # \&$symbol is except from strict 'refs'.
$sub->()
But you requested that we avoid using symbolic reference. That's way too complex. (It's also might not handle weird but legit misuse of colons.)
my $pkg = \%::;
my $sub_name = $qualified_sub_name;
$pkg = $pkg->{$1} while $sub_name =~ s/^(.*?::)//sg;
my $sub = $pkg->{$sub_name};
$sub = *{ $pkg->{$sub_name} }{CODE}
if ref(\$sub) eq 'GLOB'; # Skip if glob optimized away.
$sub->()
You can use can:
my $sub_name = 'foo';
my $coderef = main->can($sub_name);
$coderef->(#args);
As others have mentioned, you should note that this can return also methods like "can" or "isa".
Also, if $sub_name contains Some::Module::subname, this will also be called.
If you're not sure what's in $sub_name, you probably want a different approach.
Use this only if you have control over $sub_name and it can contain only expected values. (I assumed this, that's why I wrote this answer.)
I have been reading about Perl recently and am slightly perplexed about how Perl handles arguments passed to subroutines.
In a language like Python, Java or PHP, a function definition takes the form (in pseudocode):
function myFunc(arg1, arg2) {
// Do something with arg1 and arg2 here
}
Yet in Perl it's just:
sub mySub {
# #_ holds all arguments passed
}
And as I understand it, that's the only way to do it.
What if I want to restrict the caller to only pass two arguments?
Isn't this just Perl not allowing anything but variable-number arguments in other languages (i.e., Python, C, etc.)?
Wouldn't that become a problem at some point?
What about all the default argument-number checking in other languages? Would one have to do that explicitly in Perl? For instance
sub a_sub {
if (#_ == 2) {
# Continue function
}
else {
return false
}
}
You are wary of the Perl environment because it is quite different from the languages you have come across before.
The people who believe in strong typing and function prototypes will disagree here, but I believe that restrictions like that are rarely useful. Has C really caught you passing the wrong number of parameters to a function often enough to be useful?
It is most common in modern Perl to copy the contents of #_ to a list of lexical scalar variables, so you will often see subroutines starting with
sub mysub {
my ($p1, $p2) = #_;
... etc.
}
that way, all parameters that are passed will be available as elements of #_ ($_[0], $_[1] etc.) while the expected ones are named and appear in $p1 and $p2 (although I hope you understand that those names should be chosen appropriately).
In the particular case that the subroutine is a method, the first parameter is special. In other languages it is self or this, but in Perl it is simply the first parameter in #_ and you may call it what you like. In those circumstances you would see
sub method {
my $self = shift;
my ($p1, $p2) = #_;
... etc.
}
so that the context object (or the name of the class if it is a class method) is extracted into $self (a name assumed by convention) and the rest of the parameters remain in #_ to be accessed either directly or, more usually, copied to local scalar variables as $p1, $p2 etc.
Most often the complaint is that there is no type checking either, so I can pass any scalar I like as a subroutine parameter. As long as use strict and use warnings are in context, even this is generally simple to debug, simply because the operations that the subroutine can perform on one form of scalar are usually illegal on another.
Although it was originally more to do with encapsulation with respect to object-oriented Perl, this quote from Larry Wall is very relevant
Perl doesn't have an infatuation with enforced privacy. It would prefer that you stayed out of its living room because you weren't invited, not because it has a shotgun
C was designed and implemented in the days when it was a major efficiency boost if you could get a faulty program to fail during compilation rather than at run time. That has changed now, although a similar situation has arisen with client-side JavaScript where it actually would be useful to know that the code is wrong before fetching the data from the internet that it has to deal with. Sadly, JavaScript parameter checking is now looser than it should be.
Update
For those who doubt the usefulness of Perl for teaching purposes, I suggest that it is precisely because Perl's mechanisms are so simple and direct that they are ideal for such purposes.
When you call a Perl subroutine all of the parameters in the call are aliased in #_. You can use them directly to affect the actual parameters, or copy them to prevent external action
If you call a Perl subroutine as a method then the calling object or class is provided as the first parameter. Again, the subroutine (method) can do what it likes with #_
Perl doesn't manage your argument handling for you. Instead, it provides a minimal, flexible abstraction and allows you to write code that fits your needs.
Pass By Reference
By default, Perl sticks an alias to each argument in #_. This implements basic, pass by reference semantics.
my $num = 1;
foo($num);
print "$num\n"; # prints 2.
sub foo { $_[0]++ }
Pass by reference is fast but has the risk of leaking changes to parameter data.
Pass By Copy
If you want pass by copy semantics, you need to make the copies yourself. Two main approaches to handling lists of positional parameters are common in the Perl community:
sub shifty {
my $foo = shift;
}
sub listy {
my ($foo) = #_;
}
At my place of employment we do a version of listy:
sub fancy_listy {
my ($positional, $args, #bad) = #_;
die "Extra args" if #bad;
}
Named Parameters
Another common practice is the use of named parameters:
sub named_params {
my %opt = #_;
}
Some people are happy with just the above. I prefer a more verbose approach:
sub named_params {
my %opt = #_;
my $named = delete $opt{named} // "default value";
my $param = delete $opt{param}
or croak "Missing required 'param'";
croak "Unknown params:", join ", ", keys %opt
if %opt;
# do stuff
}
This unpacks named params into variables, allows space for basic validation and default values and enforces that no extra, unknown arguments were passed in.
On Perl Prototypes
Perl's "prototypes" are not prototypes in the normal sense. They only provide compiler hints that allow you to skip parenthesis on function calls. The only reasonable use is to mimic the behavior of built-in functions. You can easily defeat prototype argument checking. In general, DO NOT USE PROTOTYPES. Use them with with care that you would use operator overloading--i.e. sparingly and only to improve readability.
For some reason, Perl likes lists, and dislikes static typing. The #_ array actually opens up a lot of flexibility, because subroutine arguments are passed by reference, and not by value. For example, this allows us to do out-arguments:
my $x = 40;
add_to($x, 2);
print "$x\n"; # 42
sub add_to { $_[0] += $_[1] }
… but this is more of an historic performance hack. Usually, the arguments are “declared” by a list assignment:
sub some_sub {
my ($foo, $bar) = #_;
# ^-- this assignment performs a copy
...
}
This makes the semantics of this sub call-by-value, which is usually more desirable. Yes, unused arguments are simply forgotten, and too few arguments do not raise any automatic error – the variables just contain undef. You can add arbitrary validation e.g. by checking the size of #_.
There exist plans to finally make named parameters available in the future, which would look like
sub some_sub($foo, $bar) { ... }
You can have this syntax today if you install the signatures module. But there is something even better: I can strongly recommend Function::Parameters, which allows syntax like
fun some_sub($foo, $bar = "default value") { ... }
method some_method($foo, $bar, :$named_parameter, :$named_with_default = 42) {
# $self is autodeclared in methods
}
This also supports experimental type checks.
Parser extensions FTW!
If you really want to impose stricter parameter checks in Perl, you could look at something like Params::Validate.
Perl does have the prototyping capability for parameter placeholders, that you're kind of used to seeing, but it's often unnecessary.
sub foo($){
say shift;
};
foo(); # Error: Not enough arguments for main::foo
foo('bar'); # executes correctly
And if you did sub foo($$){...} it would require 2 non-optional arguments (eg foo('bar','baz'))
You can just use:
my ($arg1, $arg2) = #_;
To explicitly limit the number of arguments you can use:
my $number =2;
die "Too many arguments" if #_ > $number;
If you are reading about Perl recently, please read about recent Perl. You may read the Modern Perl book for free as well.
Indeed, while with old standard Perl you would need to restrict the number of arguments passed to a subroutine manually, for example with something like this:
sub greet_one {
die "Too many arguments for subroutine" unless #_ <= 1;
my $name = $_[0] || "Bruce";
say "Hello, $name!";
}
With modern Perl you can take advantage of function signatures.
Here are a few examples from the Modern Perl book:
sub greet_one($name = 'Bruce') {
say "Hello, $name!";
}
sub greet_all($leader, #everyone) {
say "Hello, $leader!";
say "Hi also, $_." for #everyone;
}
sub make_nested_hash($name, %pairs) {
return { $name => \%pairs };
}
Please, note that function signatures were introduced in Perl 5.20 and considered experimental until Perl 5.36.
Therefore, if you use a Perl version in that range you may want to disable warnings for the "experimental::signatures" category:
use feature 'signatures';
no warnings 'experimental::signatures';
Parameters to perl subs are passed in #_. To make my programs easier to read, I've always used this pattern to get named parameters:
sub foo1 {
my ($bar, $baz) = #_;
do_something($bar,$baz);
}
but it causes $_[0] and $_[1] to be copied. If I were to access $_[0] directly instead of accessing $bar in the above pattern, I have call-by-value/alias access to the callers parameters with the usual caveats of call-by-reference, but it is much faster (see demo below).
I'm left with this suspicion, that the my ($param1, $param2 ...) = #_; pattern is bad for performance reasons. So I find I have to choose between fast and readable programs which is, well, an impossible choice.
I end up writing subs where performance is the focus with $_[<n>] and everything else with the pattern above. Trouble is, often I don't know beforehand where the bottlenecks are ;-)
Is there a way to get named parameters that are also fast? Or what seems to be canon on the matter? $_[0] or $bar?
Appendix: Speed demo
use Time::HiRes qw(time);
# Lets just do *something* with the parameters - here we just add up all
# their lengths
my $totalLength = 0;
sub foo1 {
# Access $_[0] directly - effectively call-by-reference
$totalLength += length($_[0]);
}
sub foo2 {
# Access a copy of $_[0] - effectively call-by-value - involves
# copying
my ($bar) = #_;
$totalLength += length($bar);
}
my $a = 'b' x 10_000;
my $t0 = time;
foreach (0..1_000_000) {
foo1($a);
}
printf "foo1 %2.6f\n", time - $t0;
$t0 = time;
foreach (0..1_000_000) {
foo2($a);
}
printf "foo2 %2.6f\n", time - $t0;
Prints out
foo1 0.329470
foo2 1.280364
foo1 is almost 4 times faster than foo2 because it avoids copying $_[0].
Pass them via a hashref:
my %args = (bar=>1, baz=>2);
mySub(\%args);
sub mySub {
my $args = shift;
doSomething($args); # pass entire parameter list for cheap!
doSomething2($args{bar}); # Use specific parameter
}
Frankly, I have my slight doubts about the performance benefits (hash access isn't free) but you can benchmark it if you really need to. But this isn't the best performance option (see below) and may not even be needed (see last part), and this I don't see much need to try.
Another option (which kinda sucks but is better for performance) is to use $_[1] etc... but combat non-readability via extensive comments.
# pass `baz`
doSomething($_[1]);
Another even-higher-performance-but-bad-design option is to bypass the parameter passing alltogether, and use global variables to pass parameters.
our $bar = 1;
mySub();
sub mySub {
#do something with $bar. Pray some other code didn't clobber it
}
Last consideration:
If your code is so well-tuned AND so performance-sensitive that copying a couple of scalars makes a significant difference, you MAY want to drop out of Perl into pure C for those functions.
But, as Knuth said, please don't optimize prematurely.
First, profile your entire app and make sure that the scalar parameter copying is indeed where your biggest bottlenecks are. I don't dispute that this is plausible, but typically, bottlenecks are elsewhere (IO, DB, slow data structures, etc...).
In other words, the fact that $operation_X can be implemented 4 times faster, means nothing if $operation_X takes up a total of 0.01% of your runtime. Speeding it up by a factor of 4 is simply not worth the trouble given decreased readability.
Well, if you're passing $bar and $baz, in that order, to sub do_something(), another bad option is to use the following scary -- but documented -- syntax:
sub foo1 { goto &do_something}
...which would pass the context on to do_something() immediately. No help with documenting the parameters, but it's possibly the fastest pass-on-to-another-routine mechanism of the bunch. :-)
Heck, I'd downvote this answer myself....
I am seeing both of them used in this script I am trying to debug and the literature is just not clear. Can someone demystify this for me?
The short answer is that my marks a variable as private in a lexical scope, and local marks a variable as private in a dynamic scope.
It's easier to understand my, since that creates a local variable in the usual sense. There is a new variable created and it's accessible only within the enclosing lexical block, which is usually marked by curly braces. There are some exceptions to the curly-brace rule, such as:
foreach my $x (#foo) { print "$x\n"; }
But that's just Perl doing what you mean. Normally you have something like this:
sub Foo {
my $x = shift;
print "$x\n";
}
In that case, $x is private to the subroutine and its scope is enclosed by the curly braces. The thing to note, and this is the contrast to local, is that the scope of a my variable is defined with respect to your code as it is written in the file. It's a compile-time phenomenon.
To understand local, you need to think in terms of the calling stack of your program as it is running. When a variable is local, it is redefined from the point at which the local statement executes for everything below that on the stack, until you return back up the stack to the caller of the block containing the local.
This can be confusing at first, so consider the following example.
sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }
$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect
When foo is called the first time, it sees the global value of $x which is 1. When bar is called and local $x runs, that redefines the global $x on the stack. Now when foo is called from bar, it sees the new value of 2 for $x. So far that isn't very special, because the same thing would have happened without the call to local. The magic is that when bar returns we exit the dynamic scope created by local $x and the previous global $x comes back into scope. So for the final call of foo, $x is 1.
You will almost always want to use my, since that gives you the local variable you're looking for. Once in a blue moon, local is really handy to do cool things.
Dynamic Scoping. It is a neat concept. Many people don't use it, or understand it.
Basically think of my as creating and anchoring a variable to one block of {}, A.K.A. scope.
my $foo if (true); # $foo lives and dies within the if statement.
So a my variable is what you are used to. whereas with dynamic scoping $var can be declared anywhere and used anywhere.
So with local you basically suspend the use of that global variable, and use a "local value" to work with it. So local creates a temporary scope for a temporary variable.
$var = 4;
print $var, "\n";
&hello;
print $var, "\n";
# subroutines
sub hello {
local $var = 10;
print $var, "\n";
&gogo; # calling subroutine gogo
print $var, "\n";
}
sub gogo {
$var ++;
}
This should print:
4
10
11
4
Quoting from Learning Perl:
But local is misnamed, or at least misleadingly named. Our friend Chip Salzenberg says that if he ever gets a chance to go back in a time machine to 1986 and give Larry one piece of advice, he'd tell Larry to call local by the name "save" instead.[14] That's because local actually will save the given global variable's value away, so it will later automatically be restored to the global variable. (That's right: these so-called "local" variables are actually globals!) This save-and-restore mechanism is the same one we've already seen twice now, in the control variable of a foreach loop, and in the #_ array of subroutine parameters.
So, local saves a global variable's current value and then set it to some form of empty value. You'll often see it used to slurp an entire file, rather than leading just a line:
my $file_content;
{
local $/;
open IN, "foo.txt";
$file_content = <IN>;
}
Calling local $/ sets the input record separator (the value that Perl stops reading a "line" at) to an empty value, causing the spaceship operator to read the entire file, so it never hits the input record separator.
I can’t believe no one has linked to Mark Jason Dominus’ exhaustive treatises on the matter:
Coping with Scoping
And afterwards, if you want to know what local is good for after all,Seven Useful Uses of local
http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()
Unlike dynamic variables created by
the local operator, lexical variables
declared with my are totally hidden
from the outside world, including any
called subroutines. This is true if
it's the same subroutine called from
itself or elsewhere--every call gets
its own copy.
http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()
A local modifies its listed variables
to be "local" to the enclosing block,
eval, or do FILE --and to any
subroutine called from within that
block. A local just gives temporary
values to global (meaning package)
variables. It does not create a local
variable. This is known as dynamic
scoping. Lexical scoping is done with
my, which works more like C's auto
declarations.
I don't think this is at all unclear, other than to say that by "local to the enclosing block", what it means is that the original value is restored when the block is exited.
Well Google really works for you on this one: http://www.perlmonks.org/?node_id=94007
From the link:
Quick summary: 'my' creates a new
variable, 'local' temporarily amends
the value of a variable.
ie, 'local' temporarily changes the
value of the variable, but only
within the scope it exists in.
Generally use my, it's faster and doesn't do anything kind of weird.
From man perlsub:
Unlike dynamic variables created by the local operator, lexical variables declared with my are totally hidden from the outside world, including any called subroutines.
So, oversimplifying, my makes your variable visible only where it's declared. local makes it visible down the call stack too. You will usually want to use my instead of local.
Your confusion is understandable. Lexical scoping is fairly easy to understand but dynamic scoping is an unusual concept. The situation is made worse by the names my and local being somewhat inaccurate (or at least unintuitive) for historical reasons.
my declares a lexical variable -- one that is visible from the point of declaration until the end of the enclosing block (or file). It is completely independent from any other variables with the same name in the rest of the program. It is private to that block.
local, on the other hand, declares a temporary change to the value of a global variable. The change ends at the end of the enclosing scope, but the variable -- being global -- is visible anywhere in the program.
As a rule of thumb, use my to declare your own variables and local to control the impact of changes to Perl's built-in variables.
For a more thorough description see Mark Jason Dominus' article Coping with Scoping.
local is an older method of localization, from the times when Perl had only dynamic scoping. Lexical scoping is much more natural for the programmer and much safer in many situations. my variables belong to the scope (block, package, or file) in which they are declared.
local variables instead actually belong to a global namespace. If you refer to a variable $x with local, you are actually referring to $main::x, which is a global variable. Contrary to what it's name implies, all local does is push a new value onto a stack of values for $main::x until the end of this block, at which time the old value will be restored. That's a useful feature in and of itself, but it's not a good way to have local variables for a host of reasons (think what happens when you have threads! and think what happens when you call a routine that genuinely wants to use a global that you have localized!). However, it was the only way to have variables that looked like local variables back in the bad old days before Perl 5. We're still stuck with it.
"my" variables are visible in the current code block only. "local" variables are also visible where ever they were visible before. For example, if you say "my $x;" and call a sub-function, it cannot see that variable $x. But if you say "local $/;" (to null out the value of the record separator) then you change the way reading from files works in any functions you call.
In practice, you almost always want "my", not "local".
Look at the following code and its output to understand the difference.
our $name = "Abhishek";
sub sub1
{
print "\nName = $name\n";
local $name = "Abhijeet";
&sub2;
&sub3;
}
sub sub2
{
print "\nName = $name\n";
}
sub sub3
{
my $name = "Abhinav";
print "\nName = $name\n";
}
&sub1;
Output is :
Name = Abhishek
Name = Abhijeet
Name = Abhinav
&s;
sub s()
{
local $s="5";
&b;
print $s;
}
sub b()
{
$s++;
}
The above script prints 6.
But if we change local to my it will print 5.
This is the difference. Simple.
It will differ only when you have a subroutine called within a subroutine, for example:
sub foo {
print "$x\n";
}
sub bar { my $x; $x = 2; foo(); }
bar();
It prints nothing as $x is limited by {} of bar and not visible to called subroutines, for example:
sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }
bar();
It will print 2 as local variables are visible to called subroutines.
dinomite's example of using local to redefine the record delimiter is the only time I have ran across in a lot of perl programming. I live in a niche perl environment [security programming], but it really is a rarely used scope in my experience.
I think the easiest way to remember it is this way. MY creates a new variable. LOCAL temporarily changes the value of an existing variable.
#!/usr/bin/perl
sub foo { print ", x is $x\n"; }
sub testdefault { $x++; foo(); } # prints 2
sub testmy { my $x; $x++; foo(); } # prints 1
sub testlocal { local $x = 2; foo(); } # prints 2. new set mandatory
print "Default, everything is global";
$x = 1;
testdefault();
print "My does not affect function calls outside";
$x = 1;
testmy();
print "local is everything after this but initializes a new";
$x = 1;
testlocal();
As mentioned in testlocal comment, declaring "local $x;" means that $x is now undef