|
|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
| (slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix | |||||||
While there are some reason to criticize Perl of excessive fascination with digrams and trigrams, Perl like an icebreaker opened for newer languages interesting avenues in the lexical structure of the language. For example, IMHO, it is is under influence of Perl Python got such lexical elements as r, b and f strings as well and triple quoted strings.
I think that this level of understanding of Perl is typical for "level-zero" comparisons done by level-zero programmers ;-). As soon as an article claims that Perl is less readable that Python (or other language) this is telling indication that the article is junk and the author does not understand what he is writing about. Or more charitably it reflects superficial problems with the language typical for novices, who are limited to "toy" programs. Other features of the language are in play as for readability of medium and large programs.
For example, in the article Dive Deep Into Python Vs Perl Debate - What Should I Learn Python or Perl (there is nothing deep in this article; it is extremely superficial) the author claims:
Perl has a very complex code which makes it difficult to understand for a novice. Subroutines, and even other symbols like:
'$`','$&'etc are hard to understand and program for a less experienced programmer. Also, Perl code when read would be difficult and complex to understand unless you have a quality experience.
In reality, sigils like "$" do not badly affect readability in most cases, and can even add to it. For example, this solution automatically prevents using variable names identical to reserved keywords or names of built-in functions, which is problem that Python programmers, especially those who have experience with other languages, need to deal with.
The real readability issues for medium and large size programs revolve around the concepts of lifespan, visibility of variables and handling of namespaces. They are not limited or even greatly influenced by the lexical level. The idea of namespaces is the generalization of the concept of global and local variables on a new, revolutionary level qhch makes access to them similar to the access of files in Unix. They were introduced along with the concept of Modules in Nodule -- the language developed by Nicklaus Wirth in the mid-1970s, It was quickly discontinued and replaces with Modula-2 developed between 1977 and 1985 which achieves some level of popularity in system programming and survived to this day.
The most important issue that defines readability is the rules for visibility of the variables. This is the area were Python beats Perl, as in Python global variables are visible within subroutines but can't be changed without using global keyword to define them. This is pretty ingenious, elegant solution for a very difficult and important problem. In Perl global variables are not only visible in subroutines, but can't be changes in them. Attempt to change them creates a local variable with the same name (which might be not what programmer intended, and as no warning were given by interpreter, this is a double edge sword which might introduce subtle errors in the program)
Moreover in Perl is you assign a value of variable not declared as my in a subroutine to the variable that variable enters the global scope. Which often is undesirable. And for one letter variables often used for indexes such as $i, $j, $k, $l, $m invites troubles.
In Python all variables the value to which is first assigned within the subroutine are automatically assumed to be local. That eliminates the need to my keyword, which in Perl compensates excessive visibility global variables.
The second issue is the ability to specify the lifespan of the variables. Typically local variables are what PL/1 (which is the language which originated many concepts used in later languages) were called "automatic" variables and Perl calls my variable: the storage for them is allocated at the entry to the subroutine and is destroyed at the exit (they are sometimes called stack variables). The other type of variable often called external in PL/1 (but that has nothing to do with visibility) are allocated at the beginning of execution of the script and exists for the whole direction of program. Their visibility can be local or global. so visibility is assigned independently of lifespan. In PL/1 they are called static as storage for them was allocated during compilation and included into object file and in case they are global they are called external. Now all variables are allocated on the heap, so the word "static" is incorrect but still reflects the essence.
In this area Perl has what Python is lacking and what greatly help structuring and understanding of large programs: local variables with the lifespan of global variables (which preserve their value from one invocation to another). Thos variables called state help to lessen the number of interactions between subroutines, in a way which in Python requires usage of classes. And this feature of Python stimulates the abuse of OO for tasks that does not fit this paradigm, which negatively affects readability and increase the number of lines of code.
The third important issue is namespaces. which becomes the dominant issue in readability as program size increases (say, above, 10K lines.) For a large program it is absolutely essential to partition namespace into separate sub-namespaces and specify the rules of visibility for those variables. This is called exporting of the variable.
As for namespaces Perl is more flexible then Python -- in Python namespace are replica of Module namespaces and are firmly associated with the module ("one module --one namespace). In Perl you can define additional namespaces when you need them within the same modules, using the "package" keyword. Both languages allow to access variables from a different namespaces by qualification them with the the name of the namespace -- a similar mechanism that is used in Unix for accessing files, when you need to specify path, when you are accessing a file from a different directory. Here Perl is more flexible then Python because in Perl you can also specify set of variables visible externally in the module, but you can import only a fraction of them in each of other modules from this namespace.
The other approach is use of subclasses in OO, but this is another story and this approach has certain advantages and drawbacks and is less important in comparison with the revolutionary concept of the module introduced by Wirth in Module language. The critical part of success of OO success is not object orientation (which is an obscure and questionable concept, outside few application domains) but the implementation of hierarchical namespaces model, in which siblings has access to parent namespace.
The main problem in writing large programs is:
This is a critical part of success of OO success is not object orientation (which is an obscure and questionable concept, outside few application domains) but the implementation of hierarchical namespaces model, in which siblings has access to parent namespace.
One of the most interesting feature of Perl is that unlike other languages it has an explicit concept of namespaces. Each namespace defines a separate symbol table, which is basically a hash with a key for each identifier. In other words in Perl you can have as many user-defined symbol tables as you wish (as many as the number of package statements you use). They are the instrument to segregate code so that one piece of code does not conflict with another.
Namespace are analyzed and created by Perl interpreter in compile time, not run time. Each new namespace is started when the interpreter encounters the package statement. At this point it creates a new symbol table with the name defines by the statement. All identifiers of variables encounted from this point will be put in this namespace, until the interpreter encounter the next package statement.
If there is no package statement all variables are out in the default namespace called main (which is a global namespace for Perl).
Namespaces allow you segregate variables and functions into different folders like files in Unix filesystem. In other words they play the role similar to the role of directories in Unix system where full path for the file distinguishes it from the file with the same name but located in different directory. Variables in different namespaces can even have the same name, but they are completely distinct from one another. Namespaces hold only "global" (for a given namespace) variables names, my variables names that have lexical scope of a block are held separately.
A symbol table in Perl is implemented as a hash that holds all of the names defined in a namespace. Each variable and function name belongs to some symbol table (namespace). The hash for each namespace is named after the namespace with two colons. For example, the symbol table for the namespace utils is called %utils::.
That means that you can to access them from your program with regular means of accessing hashes. For example:
DB<3> foreach $s (keys %main::) { print "$s\n"}
version::
tag_start
chunk_insertion_date
tag_exists
date_start
found_news_section
Devel::
extract_h4_timestamp
crc32
h4_timestamp_end
global_h4
DIFF
Regexp::
dirs_visited
^
top_severity
UNIVERSAL::
Tk::
title
overload::
BASE
author
all
dir
detag
If you want to address a variable in other namespace that the current you need to provide "full path" alike addressing Unix files. For example to access subroutine put_message from namespace utils you need to write:
&utils::put_message("this is warning");
Here we call the function put_message from the namespace utils. In using Unix filesystem terms it would be a file put_message in the directory /utils while in Perl this is symbol put_message in the namespace utils.
SUMMARY: In Perl each new namespace is defined by package statement which is a compile time statement as it is influence the construction of symbol table which is compile-time activity.
The main namespace in Perl is called main:: . It is used for all variables as a default if no namespace statement exists. To access variables from all other namespace in the main namespace require qualification with the namespace name if they are accessed outside the scope of package statement which defines this namespace. You can export variable from other named namespaces into main:: so that you can use them without qualification by the namespace name.
The global namespace main:: contains many special variables (such as $_ or %ENV) which are automatically visible from all packages. Some other special variables, such as @INC, $AUTOLOAD, or $a and $b in a sort block also are global in nature and belong to the main namespace by default. @INC and %INC are built-in variables that define the list of directories were library or module will be searched for loading with use or require statements
Each new namespace with the exception of default (main::) is introduced by package statement. It has just one argument: package name. By convention, package names start with a capital letter, and you should follow that convention when you create your own packages. The scope of a package statement is from the this statement to the next package statement at the same level of nesting or the end of the innermost enclosing block.
The term package is described in "Programming Perl" as:
A quantity of code that values its privacy, and tries to keep other code from trespassing upon its namespace by fencing all of its private belongings (variables and subroutines) into its own area. A variable or subroutine mentioned in the package belongs only to that package, even if there's another variable or subroutine with an identical name in some other package.
All identifiers located with the scope of package declaration belong to the namespace declared in the package statement. They will be placed in the symbol table with this name.
my variables).::) before the identifier's name, i.e., $Package::varname.main package is assumed. For example, $var and $::var
are the same as $main::var. Packages may be nested inside other packages. However, the package name must still be fully qualified. For example, if the package
Province is declared inside the package Nation, a variable in the Province package is called as $Nation::Province::var.
You cannot use a "relative" package name such as $Province::var within the Nation package for the same thing.
The default main namespace contains all other packages within it.
There is a very readable description of namespaces and typeglobs in Chapter 3 of "Advanced Perl Programming." It is worth reading for no other reason that to understand how Perl keeps track of scalars, arrays, etc. internally. The author uses graphics in his explanations. It also fully explains the difference between dynamic ('local') and lexical ('my') scoping of variables.
You can put a package declaration anywhere you can put a statement. Again, it is very important to understand that this is a compile time statement. You can also switch back into previous namespace in more than one place; package statement merely determines which symbol table is used by the compiler for the rest of that block.
That means that a given namespace can be used in multiple files.
Like Unix directories Perl namespaces are hierarchical and one namespace can be a part of another. The Unix filesystem's tremendous power and flexibility comes from the ability to put files in a multilevel directory tree and then locate them using the directory path. This makes it possible to access ten of thousands files belonging to operating system and various applications. Files with the same name but in different directories can coexist. For example:
/etc/hosts /etc/sysconfig/hostsThe same is true for Perl namespaces. Perl can stores functions and variables inside a complex hierarchy of namespaces too. The above herarchy would be represented in Perl as:
$etc::hosts $stc::sysconfig::hosts
Like directory can store any type of file, namespaces can store any type of variables: scalar, arrays, hashes, functions, etc. The digram '::' serves as the separator between hierarchically organized namespaces, just as '/' is the separator in the UNIX world. There are two basic ways to specify the namespace to which a variable belongs:
Global::execute();refers to the function execute in the namespace Global.
$Mail::message;refers to the scalar message in the namespace Mail
print keys(%my::important::addresses);prints out the keys of the hash %addresses in the namespace my::important
You can use the variable "%namespace::" to get a list of all the symbols declared in a given namespace. For example:
foreach $key (keys %Time::) {
print "\$$key => $Time::{$key}\n"
print "\@$key => @$Time::{$key}\n";
print "\%$key => @{[%$Time::{$key}\n"]}\n";
}
Assignment to a typeglobis an aliasing operation; that is, *dick = *richard; causes variables, subroutines, formats, and file and directory handles accessible via the identifier richard to also be accessible via the symbol dick . If you want to alias only a particular variable or subroutine, assign a reference instead: *dick = \$richard;
Another use of symbol tables is for making "constant" scalars:
*PI = \3.14159265358979;
Now you cannot alter $PI , which is probably a good thing, all in all. This isn't the same as a constant subroutine, which is optimized at compile time. A constant subroutine is one prototyped to take no arguments and to return a constant expression; see "Inlining Constant Functions"
The use constant pragma is a convenient shorthand:
use constant PI => 3.14159;
In addition to namespaces Perl provides three options for segregating code into independent semi-isolated parts:
If we want to get Perl to read that file and use it as part of our own program, we have three ways of doing this:
Use is now dominant form and all standard modules are included via the use statement.
Perl documentation has man page for package statement.
perlmod -- Perl modules (packages and symbol tables), perlmodlib describes Perl stndard module
In two recommended free books
Useful articles are:
Some useful documents and informative posts are available at the Web sites www.perl.com and PerlMonks
Here's the entry for 'package' in the perlfunc manpage:
package NAMESPACE
Declares the compilation unit as being in the given
namespace. The scope of the package declaration is from the
declaration itself through the end of the enclosing block
(the same scope as the local() operator). All further
unqualified dynamic identifiers will be in this namespace. A
package statement affects only dynamic variables--including
those you've used local() on--but not lexical variables
created with my(). Typically it would be the first
declaration in a file to be included by the require or use
operator. You can switch into a package in more than one
place; it influences merely which symbol table is used by the
compiler for the rest of that block. You can refer to
variables and filehandles in other packages by prefixing the
identifier with the package name and a double colon:
$Package::Variable. If the package name is null, the
main package as assumed. That is, $::sail is equivalent to
$main::sail.
The perl namespaces extension is designed as replacement of the standard means of declaring and importing symbols, such as the pragma use strict 'vars' and Exporter interface for modules. It makes the symbol lookup rules more similar to those in C++ :
package AA::BB; my $x=new BB(1); # instead of new AA::BB(1); package AA; my $y=BB->new(1); # or AA::BB->new(1);
The names of the nested packages can be imported to other packages as well.Note: the namespace lookup rules apply only to subpackage names specified as constant unquoted ("bare") strings. If the package name to be found is variable, use the following function: namespace::lookup_class('package_name', 'class_name') , where package_name is the package to start the search from (e.g. __PACKAGE__).
declare $x;initial value is undef (empty for arrays)
declare $x=123;
with given initial valueThe declaration must be executed prior to all references to the variable, regardless whether from the own package or from a nested package or other importing package. However, the declaration does not have to be the first in lexical sense, that is, it can be put at the end of the script or even in another module included sometime later.
Every variable must be declared only once.Violation of these two rules leads to an exception (die) raised by the first access to the variable.
The standard statement use vars '$x'; is also accepted as a declaration.The namespace extension is implemented as a special compilation mode. It can be enabled and disabled for each lexical scope, just like use strict. Each package activated during the namespace compilation mode (with the package statement) is treated later as using namespaces, even if other parts of it are compiled in the standard, non-namespace mode. Mixing of both modes in one package is not a very good practice, however, as it could lead to unexpected exceptions caused by undeclared variables.
use namespaces; no namespaces;Enables or disables the namespaces mode. The setting lasts up to the end of the current lexical scope. Note that the compilation of each source file starts with disabled namespace mode, even if the require or use statement which caused its inclusion lies in the namespace-enabled scope.
Enabling the namespace mode automatically implies no strict 'vars' and vice versa.use namespaces 'AA', 'BB::CC', ...;Enables the namespace mode and sets the import list for all packages defined later in the current lexical scope. This is the analogon of the C++ directive using namespace ... .
The importing relation between packages is transitive. For example, the lookup list for the packages compiled after the statement shown above will consist of AA, the packages imported by AA, BB::CC, the packages imported by BB::CC, BB, and the packages imported by BB. To avoid multiple searches, duplicates in the lookup list are removed immediately.
no namespaces 'AA', 'BB::CC', ...;Removes the named packages from the current import list, but lets the namespace compilation mode active. Note that this change will affect only packages defined after this statement.
Each reference to a variable, both reading and writing, is first checked whether it refers to a declared or imported variable. If not, and the name is unqualified, then a declared variable with this name is looked up in all packages comprising the lookup list, as explained above. If found, the variable is imported into the current package. Otherwise an exception is raised. A qualified variable name is only checked to be pre-declared, if not, an exception is raised as well.
The lookup operation is performed once per variable and package; the declaration check is performed once per variable and each expression (script line) using it which was ever executed. This way the performance penalty is constant and comparable to that of the traditional import mechanism.
Unqualified subroutine calls are resolved in the same manner, but in the case of a failure no special exception is raised, since it will be done by the perl interpreter itself. Taking a subroutine reference \&abc involves the lookup too. There is also a special function namespaces::lookup_sub('package_name', 'sub_name') returning the code reference or undef if the lookup fails.
eval '...' statements, as well as regular expressions with deferred evaluation (like s///e operators or $(?{ }) expressions), re-establish the namespace environment for the duration of the expression compilation.
|
|
Switchboard | ||||
| Latest | |||||
| Past week | |||||
| Past month | |||||
Oct 09, 2019 | stackoverflow.com
Perl Import Package in different Namespace Ask Question Asked 1 year ago Active 7 months ago Viewed 150 times We're doing things differently. View all 8 job openings! 2
choroba ,Sep 28, 2018 at 22:17
is it possible to import (use) a perl module within a different namespace?Let's say I have a Module
A(XS Module with no methods Exported@EXPORTis empty) and I have no way of changing the module.This Module has a Method
A::opencurrently I can use that Module in my main program (package main) by calling
A::openI would like to have that module inside mypackage mainso that I can directly callopenI tried to manually push every key of
%A::into%main::however that did not work as expected.The only way that I know to achieve what I want is by using
package A;inside my main program, effectively changing the package of my program frommaintoA. Im not satisfied with this. I would really like to keep my program inside package main.Is there any way to achieve this and still keep my program in package main?
Offtopic: Yes I know usually you would not want to import everything into your namespace but this module is used by us extensively and we don't want to type A:: (well the actual module name is way longer which isn't making the situation better)in front of hundreds or thousands of calls
Grinnz ,Oct 1, 2018 at 6:26
This is one of those "impossible" situations, where the clear solution -- to rework that module -- is off limits.But, you can alias that package's subs names, from its symbol table, to the same names in
main. Worse than being rude, this comes with a glitch: it catches all names that that package itself imported in any way. However, since this package is a fixed quantity it stands to reason that you can establish that list (and even hard-code it). It is just this one time, right?main
use warnings; use strict; use feature 'say'; use OffLimits; GET_SUBS: { # The list of names to be excluded my $re_exclude = qr/^(?:BEGIN|import)$/; # ... my @subs = grep { !/$re_exclude/ } sort keys %OffLimits::; no strict 'refs'; for my $sub_name (@subs) { *{ $sub_name } = \&{ 'OffLimits::' . $sub_name }; } }; my $name = name('name() called from ' . __PACKAGE__); my $id = id('id() called from ' . __PACKAGE__); say "name() returned: $name"; say "id() returned: $id";with
OffLimits.pmpackage OffLimits; use warnings; use strict; sub name { return "In " . __PACKAGE__ . ": @_" } sub id { return "In " . __PACKAGE__ . ": @_" } 1;It prints
name() returned: In OffLimits: name() called from main id() returned: In OffLimits: id() called from mainYou may need that code in a
BEGINblock, depending on other details.Another option is of course to hard-code the subs to be "exported" (in
@subs). Given that the module is in practice immutable this option is reasonable and more reliable.
This can also be wrapped in a module, so that you have the normal, selective, importing.
WrapOffLimits.pm
package WrapOffLimits; use warnings; use strict; use OffLimits; use Exporter qw(import); our @sub_names; our @EXPORT_OK = @sub_names; our %EXPORT_TAGS = (all => \@sub_names); BEGIN { # Or supply a hard-coded list of all module's subs in @sub_names my $re_exclude = qr/^(?:BEGIN|import)$/; # ... @sub_names = grep { !/$re_exclude/ } sort keys %OffLimits::; no strict 'refs'; for my $sub_name (@sub_names) { *{ $sub_name } = \&{ 'OffLimits::' . $sub_name }; } }; 1;and now in the caller you can import either only some subs
use WrapOffLimits qw(name);or all
use WrapOffLimits qw(:all);with otherwise the same main as above for a test.
The module name is hard-coded, which should be OK as this is meant only for that module.
The following is added mostly for completeness.
One can pass the module name to the wrapper by writing one's own
importsub, which is what gets used then. The import list can be passed as well, at the expense of an awkward interface of theusestatement.It goes along the lines of
package WrapModule; use warnings; use strict; use OffLimits; use Exporter qw(); # will need our own import our ($mod_name, @sub_names); our @EXPORT_OK = @sub_names; our %EXPORT_TAGS = (all => \@sub_names); sub import { my $mod_name = splice @_, 1, 1; # remove mod name from @_ for goto my $re_exclude = qr/^(?:BEGIN|import)$/; # etc no strict 'refs'; @sub_names = grep { !/$re_exclude/ } sort keys %{ $mod_name . '::'}; for my $sub_name (@sub_names) { *{ $sub_name } = \&{ $mod_name . '::' . $sub_name }; } push @EXPORT_OK, @sub_names; goto &Exporter::import; } 1;what can be used as
use WrapModule qw(OffLimits name id); # or (OffLimits :all)or, with the list broken-up so to remind the user of the unusual interface
use WrapModule 'OffLimits', qw(name id);When used with the main above this prints the same output.
The
usestatement ends up using the import sub defined in the module, which exports symbols by writing to the caller's symbol table. (If noimportsub is written then theExporter'simportmethod is nicely used, which is how this is normally done.)This way we are able to unpack the arguments and have the module name supplied at
useinvocation. With the import list supplied as well now we have topushmanually to@EXPORT_OKsince this can't be in theBEGINphase. In the end the sub is replaced byExporter::importvia the (good form of) goto , to complete the job.Simerax ,Sep 30, 2018 at 10:19
You can forcibly "import" a function into main using glob assignment to alias the subroutine (and you want to do it in BEGIN so it happens at compile time, before calls to that subroutine are parsed later in the file):use strict; use warnings; use Other::Module; BEGIN { *open = \&Other::Module::open }However, another problem you might have here is that open is a builtin function, which may cause some problems . You can add
use subs 'open';to indicate that you want to override the built-in function in this case, since you aren't using an actual import function to do so.Grinnz ,Sep 30, 2018 at 17:33
Here is what I now came up with. Yes this is hacky and yes I also feel like I opened pandoras box with this. However at least a small dummy program ran perfectly fine.I renamed the module in my code again. In my original post I used the example
A::openactually this module does not contain any method/variable reserved by the perl core. This is why I blindly import everything here.BEGIN { # using the caller to determine the parent. Usually this is main but maybe we want it somewhere else in some cases my ($parent_package) = caller; package A; foreach (keys(%A::)) { if (defined $$_) { eval '*'.$parent_package.'::'.$_.' = \$A::'.$_; } elsif (%$_) { eval '*'.$parent_package.'::'.$_.' = \%A::'.$_; } elsif (@$_) { eval '*'.$parent_package.'::'.$_.' = \@A::'.$_; } else { eval '*'.$parent_package.'::'.$_.' = \&A::'.$_; } } }
Oct 09, 2019 | stackoverflow.com
Perl Importing Variables From Calling Module Ask Question Asked 9 years, 1 month ago Active 9 years, 1 month ago Viewed 4k times 0 1
Russell C. ,Aug 31, 2010 at 20:31
I have a Perl module (Module.pm) that initializes a number of variables, some of which I'd like to import ($VAR2, $VAR3) into additional submodules that it might load during execution.The way I'm currently setting up Module.pm is as follows:
package Module; use warnings; use strict; use vars qw($SUBMODULES $VAR1 $VAR2 $VAR3); require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw($VAR2 $VAR3); sub new { my ($package) = @_; my $self = {}; bless ($self, $package); return $self; } sub SubModules1 { my $self = shift; if($SUBMODULES->{'1'}) { return $SUBMODULES->{'1'}; } # Load & cache submodule require Module::SubModule1; $SUBMODULES->{'1'} = Module::SubModule1->new(@_); return $SUBMODULES->{'1'}; } sub SubModules2 { my $self = shift; if($SUBMODULES->{'2'}) { return $SUBMODULES->{'2'}; } # Load & cache submodule require Module::SubModule2; $SUBMODULES->{'2'} = Module::SubModule2->new(@_); return $SUBMODULES->{'2'}; }Each submodule is structured as follows:
package Module::SubModule1; use warnings; use strict; use Carp; use vars qw(); sub new { my ($package) = @_; my $self = {}; bless ($self, $package); return $self; }I want to be able to import the $VAR2 and $VAR3 variables into each of the submodules without having to reference them as $Module::VAR2 and $Module::VAR3. I noticed that the calling script is able to access both the variables that I have exported in Module.pm in the desired fashion but SubModule1.pm and SubModule2.pm still have to reference the variables as being from Module.pm.
I tried updating each submodule as follows which unfortunately didn't work I was hoping:
package Module::SubModule1; use warnings; use strict; use Carp; use vars qw($VAR2 $VAR3); sub new { my ($package) = @_; my $self = {}; bless ($self, $package); $VAR2 = $Module::VAR2; $VAR3 = $Module::VAR3; return $self; }Please let me know how I can successfully export $VAR2 and $VAR3 from Module.pm into each Submodule. Thanks in advance for your help!
Russell C. ,Aug 31, 2010 at 22:37
In your submodules, are you forgetting to sayuse Module;? Calling
use Modulefrom another package (sayModule::Submodule9) will try to run theModule::importmethod. Since you don't have that method, it will call theExporter::importmethod, and that is where the magic that exportsModule's variables into theModule::Submodule9namespace will happen.
In your program there is only one
Modulenamespace and only one instance of the (global) variable$Module::VAR2. Exporting creates aliases to this variable in other namespaces, so the same variable can be accessed in different ways. Try this in a separate script:package Whatever; use Module; use strict; use vars qw($VAR2); $Module::VAR2 = 5; print $Whatever::VAR2; # should be 5. $VAR2 = 14; # same as $Whatever::VAR2 = 14 print $Module::VAR2; # should be 14Russell C. ,Aug 31, 2010 at 21:38
Well there is the easy way:In M.pm:
package M; use strict; use warnings; #our is better than "use vars" for creating package variables #it creates an alias to $M::foo named $foo in the current lexical scope our $foo = 5; sub inM { print "$foo\n" } 1;In M/S.pm
package M; #creates an alias to $M::foo that will last for the entire scope, #in this case the entire file our $foo; package M::S; use strict; use warnings; sub inMS { print "$foo\n" } 1;In the script:
#!/usr/bin/perl use strict; use warnings; use M; use M::S; M::inM(); M::S::inMS();But I would advise against this. Global variables are not a good practice, and sharing global variables between modules is even worse.
Oct 09, 2019 | perlmaven.com
These are the oldest type of variables in Perl. They are still used in some cases, even though in most cases you should just use lexical variables.
In old times, if we started to use a variable without declaring it with the my or state keywords, we automatically got a variable in the current namespace. Thus we could write:
- $x = 42 ;
- print "$x\n" ; # 42
Please note, we don't use strict; in these examples. Even though you should always use strict . We'll fix this in a bit.
The default namespace in every perl script is called "main" and you can always access variables using their full name including the namespace:
- $x = 42 ;
- print "$x\n" ; # 42
- print "$main::x\n" ; # 42
The package keyword is used to switch namespaces:
- $x = 42 ;
- print "$x\n" ; # 42
- print "$main::x\n" ; # 42
- package Foo ;
- print "Foo: $x\n" ; # Foo:
Please note, once we switched to the "Foo" namespace, the $x name refers to the variable in the Foo namespace. It does not have any value yet.
- $x = 42 ;
- print "$x\n" ; # 42
- print "$main::x\n" ; # 42
- package Foo ;
- print "Foo: $x\n" ; # Foo:
- $x = 23 ;
- print "Foo: $x\n" ; # Foo 23;
Do we really have two $x-es? Can we reach the $x in the main namespace while we are in the Foo namespace?
- $x = 42 ;
- print "$x\n" ; # 42
- print "$main::x\n" ; # 42
- package Foo ;
- print "Foo: $x\n" ; # Foo:
- $x = 23 ;
- print "Foo: $x\n" ; # Foo 23
- print "main: $main::x\n" ; # main: 42
- print "Foo: $Foo::x\n" ; # Foo: 23
- package main ;
- print "main: $main::x\n" ; # main: 42
- print "Foo: $Foo::x\n" ; # Foo: 23
- print "$x\n" ; # 42
We even switched back to the main namespace (using package main; ) and if you look closely, you can see that while we were already in the main package we could reach to the $x of the Foo package using $Foo::x but if we accessed $x without the full package name, we reach the one in the main namespace.
Every package (or namespace) can hold variables with the same name.
Sep 21, 2019 | perl.plover.com
Coping with Scoping
© Copyright 1998 The Perl Journal. Reprinted with permission.
Cet article est également disponible en Français
Questo articolo è disponibile anche in Italiano
Dieser Artikel ist auch in deutscher Übersetzung verfügbar
Just the FAQs: Coping with ScopingIn the Beginning, some time around 1960, every part of your program had access to all the variables in every other part of the program. That turned out to be a problem, so language designers invented local variables, which were visible in only a small part of the program. That way, programmers who used a variable x could be sure that nobody was able to tamper with the contents of x behind their back. They could also be sure that by using x they weren't tampering with someone else's variable by mistake.
Every programming language has a philosophy, and these days most of these philosophies have to do with the way the names of variables are managed. Details of which variables are visible to which parts of the program, and what names mean what, and when, are of prime importance. The details vary from somewhat baroque, in languages like Lisp, to extremely baroque, in languages like C++. Perl unfortunately, falls somewhere towards the rococo end of this scale.
The problem with Perl isn't that it has no clearly-defined system of name management, but rather that it two systems, both working at once. Here's the Big Secret about Perl variables that most people learn too late: Perl has two completely separate, independent sets of variables. One is left over from Perl 4, and the other is new. The two sets of variables are called `package variables' and `lexical variables', and they have nothing to do with each other.
Package variables came first, so we'll talk about them first. Then we'll see some problems with package variables, and how lexical variables were introduced in Perl 5 to avoid these problems. Finally, we'll see how to get Perl to automatically diagnose places where you might not be getting the variable you meant to get, which can find mistakes before they turn into bugs.
Package Variables$x = 1Here, $x is a package variable . There are two important things to know about package variables:
- Package variables are what you get if you don't say otherwise.
- Package variables are always global.
Global means that package variables are always visible everywhere in every program. After you do $x = 1 , any other part of the program, even some other subroutine defined in some other file, can inspect and modify the value of $x . There's no exception to this; package variables are always global.
Package variables are divided into families, called packages . Every package variable has a name with two parts. The two parts are analogous to the variable's given name and family name. You can call the Vice-President of the United States `Al', if you want, but that's really short for his full name, which is `Al Gore'. Similarly, $x has a full name, which is something like $main::x . The main part is the package qualifier , analogous to the `Gore' part of `Al Gore'. Al Gore and Al Capone are different people even though they're both named `Al'. In the same way, $Gore::Al and $Capone::Al are different variables, and $main::x and $DBI::x are different variables.
You're always allowed to include the package part of the variable's name, and if you do, Perl will know exactly which variable you mean. But for brevity, you usually like to leave the package qualifier off. What happens if you do?
The Current PackageIf you just say $x , perl assumes that you mean the variable $x in the current package. What's the current package? It's normally main , but you can change the current package by writing
package Mypackage;in your program; from that point on, the current package is Mypackage . The only thing the current package does is affect the interpretation of package variables that you wrote without package names. If the current package is Mypackage , then $x really means $Mypackage::x . If the current package is main , then $x really means $main::x.
If you were writing a module, let's say the MyModule module, you would probably put a line like this at the top of the module file:
package MyModule;From there on, all the package variables you used in the module file would be in package MyModule , and you could be pretty sure that those variables wouldn't conflict with the variables in the rest of the program. It wouldn't matter if both you and the author of DBI were to use a variable named $x , because one of those $x es would be $MyModule::x and the other would be $DBI::x .
Remember that package variables are always global. Even if you're not in package DBI, even if you've never heard of package DBI, nothing can stop you from reading from or writing to $DBI::errstr . You don't have to do anything special. $DBI::errstr , like all package variables, is a global variable, and it's available globally; all you have to do is mention its full name to get it. You could even say
package DBI; $errstr = 'Ha ha Tim!';and that would modify $DBI::errstr .
Package Variable TriviaThere are only three other things to know about package variables, and you might want to skip them on the first reading:
- The package with the empty name is the same as main . So $::x is the same as $main::x for any x .
- Some variables are always forced to be in package main. For example, if you mention %ENV , Perl assumes that you mean %main::ENV , even if the current package isn't main . If you want %Fred::ENV , you have to say so explicitly, even if the current package is Fred . Other names that are special this way include INC , all the one-punctuation-character names like $_ and $$ , @ARGV , and STDIN , STDOUT , and STDERR .
- Package names, but not variable names, can contain :: . You can have a variable named $DBD::Oracle::x. This means the variable x in the package DBD::Oracle ; it has nothing at all to do with the package DBD which is unrelated. Isaac Newton is not related to Olivia Newton-John, and Newton::Isaac is not related to Newton::John::Olivia . Even though it appears that they both begin with Newton , the appearance is deceptive. Newton::John::Olivia is in package Newton::John , not package Newton.
That's all there is to know about package variables.
Package variables are global, which is dangerous, because you can never be sure that someone else isn't tampering with them behind your back. Up through Perl 4, all variables were package variables, which was worrisome. So Perl 5 added new variables that aren't global.
Lexical VariablesPerl's other set of variables are called lexical variables (we'll see why later) or private variables because they're private. They're also sometimes called my variables because they're always declared with my . It's tempting to call them `local variables', because their effect is confined to a small part of the program, but don't do that, because people might think you're talking about Perl's local operator, which we'll see later. When you want a `local variable', think my , not local .
The declaration
my $x;creates a new variable, named x , which is totally inaccessible to most parts of the program---anything outside the block where the variable was declared. This block is called the scope of the variable. If the variable wasn't declared in any block, its scope is from the place it was declared to the end of the file.
You can also declare and initialize a my variable by writing something like
my $x = 119;You can declare and initialize several at once:
my ($x, $y, $z, @args) = (5, 23, @_);Let's see an example of where some private variables will be useful. Consider this subroutine:
sub print_report { @employee_list = @_; foreach $employee (@employee_list) { $salary = lookup_salary($employee); print_partial_report($employee, $salary); } }If lookup_salary happens to also use a variable named $employee , that's going to be the same variable as the one used in print_report , and the works might get gummed up. The two programmers responsible for print_report and lookup_salary will have to coordinate to make sure they don't use the same variables. That's a pain. In fact, in even a medium-sized project, it's an intolerable pain.
The solution: Use my variables:
sub print_report { my @employee_list = @_; foreach my $employee (@employee_list) { my $salary = lookup_salary($employee); print_partial_report($employee, $salary); } }my @employee_list creates a new array variable which is totally inaccessible outside the print_report function. for my $employee creates a new scalar variable which is totally inaccessible outside the foreach loop, as does my $salary . You don't have to worry that the other functions in the program are tampering with these variables, because they can't; they don't know where to find them, because the names have different meanings outside the scope of the my declarations. These `my variables' are sometimes called `lexical' because their scope depends only on the program text itself, and not on details of execution, such as what gets executed in what order. You can determine the scope by inspecting the source code without knowing what it does. Whenever you see a variable, look for a my declaration higher up in the same block. If you find one, you can be sure that the variable is inaccessible outside that block. If you don't find a declaration in the smallest block, look at the next larger block that contains it, and so on, until you do find one. If there is no my declaration anywhere, then the variable is a package variable.
my variables are not package variables. They're not part of a package, and they don't have package qualifiers. The current package has no effect on the way they're interpreted. Here's an example:
my $x = 17; package A; $x = 12; package B; $x = 20; # $x is now 20. # $A::x and $B::x are still undefinedThe declaration my $x = 17 at the top creates a new lexical variable named x whose scope continues to the end of the file. This new meaning of $x overrides the default meaning, which was that $x meant the package variable $x in the current package.
package A changes the current package, but because $x refers to the lexical variable, not to the package variable, $x=12 doesn't have any effect on $A::x . Similarly, after package B , $x=20 modifies the lexical variable, and not any of the package variables.
At the end of the file, the lexical variable $x holds 20, and the package variables $main::x , $A::x , and $B::x are still undefined. If you had wanted them, you could still have accessed them by using their full names.
The maxim you must remember is:
Package variables are global variables.
local and my
For private variables, you must use my .Almost everyone already knows that there's a local function that has something to do with local variables. What is it, and how does it related to my ? The answer is simple, but bizarre:
my creates a local variable. local doesn't.
First, here's what local $x really does: It saves the current value of the package variable $x in a safe place, and replaces it with a new value, or with undef if no new value was specified. It also arranges for the old value to be restored when control leaves the current block. The variables that it affects are package variables, which get local values. But package variables are always global, and a local package variable is no exception. To see the difference, try this:
$lo = 'global'; $m = 'global'; A(); sub A { local $lo = 'AAA'; my $m = 'AAA'; B(); } sub B { print "B ", ($lo eq 'AAA' ? 'can' : 'cannot') , " see the value of lo set by A.\n"; print "B ", ($m eq 'AAA' ? 'can' : 'cannot') , " see the value of m set by A.\n"; }This prints
B can see the value of lo set by A. B cannot see the value of m set by A.What happened here? The local declaration in A saved a new temporary value, AAA , in the package variable $lo . The old value, global , will be restored when A returns, but before that happens, A calls B . B has no problem accessing the contents of $lo , because $lo is a package variable and package variables are always available everywhere, and so it sees the value AAA set by A .
In contrast, the my declaration created a new, lexically scoped variable named $m , which is only visible inside of function A . Outside of A , $m retains its old meaning: It refers the the package variable $m ; which is still set to global . This is the variable that B sees. It doesn't see the AAA because the variable with that value is a lexical variable, and only exists inside of A .
What Good is local ?Because local does not actually create local variables, it is not very much use. If, in the example above, B happened to modify the value of $lo , then the value set by A would be overwritten. That is exactly what we don't want to happen. We want each function to have its own variables that are untouchable by the others. This is what my does.
Why have local at all? The answer is 90% history. Early versions of Perl only had global variables. local was very easy to implement, and was added to Perl 4 as a partial solution to the local variable problem. Later, in Perl 5, more work was done, and real local variables were put into the language. But the name local was already taken, so the new feature was invoked with the word my . my was chosen because it suggests privacy, and also because it's very short; the shortness is supposed to encourage you to use it instead of local . my is also faster than local .
When to Use my and When to Use localAlways use my ; never use local .
Wasn't that easy?
Other Properties of my VariablesEvery time control reaches a my declaration, Perl creates a new, fresh variable. For example, this code prints x=1 fifty times:
for (1 .. 50) { my $x; $x++; print "x=$x\n"; }You get a new $x , initialized to undef , every time through the loop.
If the declaration were outside the loop, control would only pass by it once, so there would only be one variable:
{ my $x; for (1 .. 50) { $x++; print "x=$x\n"; } }This prints x=1 , x=2 , x=3 , ... x=50 .
You can use this to play a useful trick. Suppose you have a function that needs to remember a value from one call to the next. For example, consider a random number generator. A typical random number generator (like Perl's rand function) has a seed in it. The seed is just a number. When you ask the random number generator for a random number, the function performs some arithmetic operation that scrambles the seed, and it returns the result. It also saves the result and uses it as the seed for the next time it is called.
Here's typical code: (I stole it from the ANSI C standard, but it behaves poorly, so don't use it for anything important.)
$seed = 1; sub my_rand { $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; }And typical output:
16838 14666 10953 11665 7451 26316 27974 27550There's a problem here, which is that $seed is a global variable, and that means we have to worry that someone might inadvertently tamper with it. Or they might tamper with it on purpose, which could affect the rest of the program. What if the function were used in a gambling program, and someone tampered with the random number generator?
But we can't declare $seed as a my variable in the function:
sub my_rand { my $seed; $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; }If we did, it would be initialized to undef every time we called my_rand . We need it to retain its value between calls to my_rand .
Here's the solution:
{ my $seed = 1; sub my_rand { $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; } }The declaration is outside the function, so it only happens once, at the time the program is compiled, not every time the function is called. But it's a my variable, and it's in a block, so it's only accessible to code inside the block. my_rand is the only other thing in the block, so the $seed variable is only accessible to the my_rand function.
$seed here is sometimes called a `static' variable, because it stays the same in between calls to the function. (And because there's a similar feature in the C language that is activated by the static keyword.)
my Variable TriviaDeclarations
- You can't declare a variable my if its name is a punctuation character, like $_ , @_ , or $$ . You can't declare the backreference variables $1 , $2 , ... as my . The authors of my thought that that would be too confusing.
- Obviously, you can't say my $DBI::errstr , because that's contradictory---it says that the package variable $DBI::errstr is now a lexical variable. But you can say local $DBI::errstr ; it saves the current value of $DBI::errstr and arranges for it to be restored at the end of the block.
- New in Perl 5.004, you can write
foreach my $i (@list) {instead, to confine the $i to the scope of the loop instead. Similarly,
for (my $i=0; $i<100; $i++) {confines the scope of $i to the for loop.
If you're writing a function, and you want it to have private variables, you need to declare the variables with my . What happens if you forget?
sub function { $x = 42; # Oops, should have been my $x = 42. }In this case, your function modifies the global package variable $x . If you were using that variable for something else, it could be a disaster for your program.
Recent versions of Perl have an optional protection against this that you can enable if you want. If you put
use strict 'vars';at the top of your program, Perl will require that package variables have an explicit package qualifier. The $x in $x=42 has no such qualifier, so the program won't even compile; instead, the compiler will abort and deliver this error message:
Global symbol "$x" requires explicit package name at ...If you wanted $x to be a private my variable, you can go back and add the my . If you really wanted to use the global package variable, you could go back and change it to
$main::x = 42;or whatever would be appropriate.
Just saying use strict turns on strict vars , and several other checks besides. See perldoc strict for more details.
Now suppose you're writing the Algorithms::KnuthBendix modules, and you want the protections of strict vars But you're afraid that you won't be able to finish the module because your fingers are starting to fall off from typing $Algorithms::KnuthBendix::Error all the time.
You can save your fingers and tell strict vars to make an exception:
package Algorithms::KnuthBendix; use vars '$Error';This exempts the package variable $Algorithms::KnuthBendix::Error from causing a strict vars failure if you refer to it by its short name, $Error .
You can also turn strict vars off for the scope of one block by writing
{ no strict 'vars'; # strict vars is off for the rest of the block. }SummaryPackage variables are always global. They have a name and a package qualifier. You can omit the package qualifier, in which case Perl uses a default, which you can set with the package declaration. For private variables, use my . Don't use local ; it's obsolete.
You should avoid using global variables because it can be hard to be sure that no two parts of the program are using one another's variables by mistake.
To avoid using global variables by accident, add use strict 'vars' to your program. It checks to make sure that all variables are either declared private, are explicitly qualified with package qualifiers, or are explicitly declared with use vars .
Glossary
- global variable
- global
- lexical variable
- local declaration
- my
- my declaration
- my variable
- package declaration
- package qualifier
- package variable
- private variable
- scope
- use strict vars
- use vars
Notes
- The tech editors complained about my maxim `Never use local .' But 97% of the time, the maxim is exactly right. local has a few uses, but only a few, and they don't come up too often, so I left them out, because the whole point of a tutorial article is to present 97% of the utility in 50% of the space.
I was still afraid I'd get a lot of tiresome email from people saying ``You forgot to mention that local can be used for such-and-so, you know.'' So in the colophon at the end of the article, I threatened to deliver Seven Useful Uses for local in three months. I mostly said it to get people off my back about local . But it turned out that I did write it, and it was published some time later.
The Seven Useful Uses of local is now available on the web site. It appeared in The Perl Journal issue #14.
- Here's another potentially interesting matter that I left out for space and clarity. I got email from Robert Watkins with a program he was writing that didn't work. The essence of the bug looked like this:
my $x; for $x (1..5) { s(); } sub s { print "$x, " }Robert wanted this to print 1, 2, 3, 4, 5, but it did not. Instead, it printed , , , , , . Where did the values of $x go?
The deal here is that normally, when you write something like this:
for $x (...) { }Perl wants to confine the value of the index variable to inside the loop. If $x is a package variable, it pretends that you wrote this instead:
{ local $x; for $x (...) { } }But if $x is a lexical variable, it pretends you wrote this instead, instead:
{ my $x; for $x (...) { } }This means that the loop index variable won't get propagated to subroutines, even if they're in the scope of the original declaration.
I probably shouldn't have gone on at such length, because the perlsyn manual page describes it pretty well:
...the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my , it uses that variable instead of the global one, but it's still localized to the loop. (Note that a lexically scoped variable can cause problems if you have subroutine or format declarations within the loop which refer to it.)In my opinion, lexically scoping the index variable was probably a mistake. If you had wanted that, you would have written for my $x ... in the first place. What I would have liked it to do was to localize the lexical variable: It could save the value of the lexical variable before the loop, and restore it again afterwards. But there may be technical reasons why that couldn't be done, because this doesn't work either:
my $m; { local $m = 12; ... }The local fails with this error message:
Can't localize lexical variable $m...There's been talk on P5P about making this work, but I gather it's not trivial.
- Added 2000-01-05: Perl 5.6.0 introduced a new our(...) declaration. Its syntax is the same as for my() , and it is a replacement for use vars .
Without getting into the details, our() is just like use vars ; its only effect is to declare variables so that they are exempt from the strict 'vars' checking. It has two possible advantages over use vars , however: Its syntax is less weird, and its effect is lexical. That is, the exception that it creates to the strict checking continues only to the end of the current block:
use strict 'vars'; { our($x); $x = 1; # Use of global variable $x here is OK } $x = 2; # Use of $x here is a compile-time error as usualSo whereas use vars '$x' declares that it is OK to use the global variable $x everywhere, our($x) allows you to say that global $x should be permitted only in certain parts of your program, and should still be flagged as an error if you accidentally use it elsewhere.
- Added 2000-01-05: Here's a little wart that takes people by surprise. Consider the following program:
use strict 'vars'; my @lines = <>; my @sorted = sort backwards @lines; print @sorted; sub backwards { $b cmp $a }Here we have not declared $a or $b , so they are global variables. In fact, they have to be global, because the sort operator must to be able to set them up for the backwards function. Why doesn't strict produce a failure?
The variables $a and $b are exempted from strict vars checking, for exactly this reason.
javatpoint
A module is a container which holds a group of variables and subroutines which can be used in a program. Every module has a public interface, a set of functions and variables.
To use a module into your program, require or use statement can be used, although their semantics are slightly different.
The 'require' statement loads module at runtime to avoid redundant loading of module. The 'use' statement is like require with two added properties, compile time loading and automatic importing.
Namespace is a container of a distinct set of identifiers (variables, functions). A namespace would be like name::variable .
Every piece of Perl code is in a namespace.
In the following code,
- use strict;
- use warnings;
- my $x = "Hello" ;
- $main ::x = "Bye" ;
- print "$main::x\n" ; # Bye
- print "$x\n" ; # Hello
Here are two different variables defined as x . the $main::x is a package variable and $x is a lexical variable. Mostly we use lexical variable declared with my keyword and use namespace to separate functions.
In the above code, if we won't use use strict , we'll get a warning message as
- Name "main::x" used only once: possible typo at line..
The main is the namespace of the current script and of current variable. We have not written anything and yet we are already in the 'main' namespace.
By adding 'use strict', now we got the following error,
- Global symbol "$x" requires explicit package name
In this error, we got a new word 'package'. It indicates that we forgot to use 'my' keyword before declaring variable but actually it indicates that we should provide name of the package the variable resides in.
Perl Switching namespace using package keywordLook at the following code,
- use strict;
- use warnings;
- use 5.010;
- sub hii {
- return "main" ;
- }
- package two;
- sub hii {
- return "two" ;
- }
- say main::hii(); # main
- say two::hii(); # two
- say hii(); # two
- package main;
- say main::hii(); # main
- say two::hii(); # two
- say hii(); # main
Here we are using package keyword to switch from 'main' namespace to 'two' namespace.
Calling hii() with namespaces returns respective namespaces. Like , say main::hii(); returns 'main' and say two::hii(); returns 'two'.
Calling hii() without namespace prefix, returns the function that was local to the current namespace. In first time, we were in 'two' namespace. Hence it returned 'two'. In second time, we switched the namespace using package main. Hence it returns 'main'.
Nov 14, 2017 | stackoverflow.com
Brian G ,Sep 24, 2008 at 20:12
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?J.J. ,Sep 24, 2008 at 20:24
Dynamic Scoping. It is a neat concept. Many people don't use it, or understand it.Basically think of
myas 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
myvariable is what you are used to. whereas with dynamic scoping $var can be declared anywhere and used anywhere. So withlocalyou basically suspend the use of that global variable, and use a "local value" to work with it. Solocalcreates 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 4Brad Gilbert ,Sep 24, 2008 at 20:50
You didn't call the subroutines. – Brad Gilbert Sep 24 '08 at 20:50brian d foy ,Sep 25, 2008 at 18:23
Don't conditionally declare lexical variables: it has undefined behavior. – brian d foy Sep 25 '08 at 18:23Jeremy Bourque ,Sep 24, 2008 at 20:26
The short answer is thatmymarks a variable as private in a lexical scope, andlocalmarks 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,
$xis private to the subroutine and it's scope is enclosed by the curly braces. The thing to note, and this is the contrast tolocal, is that the scope of amyvariable 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 islocal, it is redefined from the point at which thelocalstatement executes for everything below that on the stack, until you return back up the stack to the caller of the block containing thelocal.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 effectWhen
foois called the first time, it sees the global value of$xwhich is 1. Whenbaris called andlocal $xruns, that redefines the global$xon the stack. Now whenfoois called frombar, 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 tolocal. The magic is that whenbarreturns we exit the dynamic scope created bylocal $xand the previous global$xcomes back into scope. So for the final call offoo,$xis 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,localis really handy to do cool things.Drew Stephens ,Sep 24, 2008 at 22:58
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,
localsaves 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.Aristotle Pagaltzis ,Sep 25, 2008 at 23:25
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
localis good for after all, Seven Useful Uses oflocaldan1111 ,Jan 28, 2013 at 11:21
Word of warning: both of these articles are quite old, and the second one (by the author's own warning) is obsolete. It demonstrates techniques for localization of file handles that have been superseded by lexical file handles in modern versions of Perl. – dan1111 Jan 28 '13 at 11:21Floegipoky ,Jan 23, 2015 at 16:51
As in Clinton was President (of the US) when the first was written – Floegipoky Jan 23 '15 at 16:51Steve Jessop ,Sep 24, 2008 at 20:21
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.
dlamblin ,Sep 24, 2008 at 20:14
Well Google really works for you on this one: http://www.perlmonks.org/?node_id=94007From 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.
Kevin Crumley ,Sep 24, 2008 at 20:27
While this may be true, it's basically a side effect of the fact that "local"s are intended to be visible down the callstack, while "my"s are not. And while overriding the value of a global may be the main reason for using "local", there's no reason you can't use "local" to define a new variable. – Kevin Crumley Sep 24 '08 at 20:271800 INFORMATION ,Jan 21, 2009 at 10:02
local does not actually define a new variable. For example, try using local to define a variable when option explicit is enabled. You need to use "our" or "my" to define a new global or local variable. "local" is correctly used to give a variable a new value – 1800 INFORMATION Jan 21 '09 at 10:021800 INFORMATION ,Jan 29, 2009 at 10:45
Jesus did I really say option explicit to refer to the Perl feature. I meant obviously "use strict". I've obviously not coded in Perl in a while – 1800 INFORMATION Jan 29 '09 at 10:45catfood ,Sep 24, 2008 at 20:18
Fromman 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,
mymakes your variable visible only where it's declared.localmakes it visible down the call stack too. You will usually want to usemyinstead oflocal.Michael Carman ,Sep 25, 2008 at 2:00
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 namesmyandlocalbeing somewhat inaccurate (or at least unintuitive) for historical reasons.
mydeclares 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
myto declare your own variables andlocalto control the impact of changes to Perl's built-in variables.For a more thorough description see Mark Jason Dominus' article Coping with Scoping .
skiphoppy ,Sep 25, 2008 at 18:52
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.
andy ,Sep 24, 2008 at 20:18
"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".
Abhishek Kulkarni ,Apr 10, 2013 at 5:44
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 = Abhinavphreakre ,Oct 1, 2008 at 16:01
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.Saravanarajan
add a comment,Aug 6, 2009 at 8:12&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.
,
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.
Nov 13, 2017 | stackoverflow.com
Rancho ,Apr 3, 2014 at 17:13
I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pmSomething like below
A.pm:
if (condition1) { $x = 'PASSED'; } if (condition2) { $x = 'FAILED'; }B.pm:
if ($x=='PASSED') { $y=1; } else { $y=0; }I tried using
require ("A.pm");in B.pm but it gives me an errorglobal symbol requires an explicit package namewhich means it is not able to read the variable from require. Any inputs would helpBorodin ,Apr 3, 2014 at 17:27
This sounds like a very strange configuration. YourA.pmhas executable code as well as values that you want to access externally. Is that code in subroutines? Are you aware that any code outside a subroutine will be executed the first time the external coderequiresthe file? You need to show us the contents ofA.pmor we can't help you much. – Borodin Apr 3 '14 at 17:27Jonathan Leffler ,Apr 3, 2014 at 17:29
Normally, you'd return$xfrom a function defined in A and called in B; this is a much cleaner, less pathological way of getting at the information. – Jonathan Leffler Apr 3 '14 at 17:29Rancho ,Apr 3, 2014 at 17:41
Yes the above if conditions in A.pm are in a subroutine. Is there a way I could read that subroutine outside to extract the value of $x? – Rancho Apr 3 '14 at 17:41ysth ,Apr 3, 2014 at 18:04
there is a core module named B - avoid using that name even in examples. – ysth Apr 3 '14 at 18:04David W. ,Apr 3, 2014 at 19:08
I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm
We could show you how to do this, but this is a really bad, awful idea.
There's a reason why variables are scoped, and even global variables declared with
ourand notmyare still scoped to a particular package.Imagine someone modifying one of your packages, and not realizing there's a direct connection to a variable name
$x. They could end up making a big mess without even knowing why.What I would HIGHLY recommend is that you use functions (subroutines) to pass around the value you need:
Local/A.pmpackage Local::A; use strict; use warnings; use lib qw($ENV