When should you use a package variable against a lexical variable (and what's the difference)?

I am looking at old Perl code on Perl Monks to figure out how to program using Win32 :: OLE and MS Word. Scattered throughout the code are variables with names such as $ MS :: Word, etc., Without the "mine" included in their declaration. After reading a bit on Google, I understand that they are called "package variables" and "lexical variables" declared with my.

My first question is: " What are package variables?" . I (think) I understand what lexical variables are, but I do not understand the purpose of the package variables or how their use differs from lexical ones, so my second question will be: " What is the difference between lexical and package variables

+4
source share
3 answers

A package variable lives in a symbol table, so given its name, you can read or change it from any other package or area. The scope of the lexical variable is determined by the program text. The "Private Variables via my ()" section of the perlsub man page provides more information on defining vocabulary.

Say we have the following MyModule.pm :

 package MyModule; # these are package variables our $Name; $MyModule::calls = "I do not think it means what you think it means."; # this is a lexical variable my $calls = 0; sub say_hello { ++$calls; print "Hello, $Name!\n"; } sub num_greetings { $calls; } 1; 

Please note that it contains the $calls package and the lexical $calls . Anyone can go to the former, but the module controls access to the latter:

 #! /usr/bin/perl use warnings; use strict; use MyModule; foreach my $name (qw/ Larry Curly Moe Shemp /) { $MyModule::Name = $name; MyModule::say_hello; } print MyModule::num_greetings, "\n"; print "calls = $MyModule::calls\n"; 

Program exit

 Hello, Larry! Hello, Curly! Hello, Moe! Hello, Shemp! 4 calls = I do not think it means what you think it means. 

As you can see, the package variables are global, so all the usual fixes and recommendations apply. Unless explicitly granted access, it is impossible for code outside the MyModule package to have access to its lexical $calls .

Rule of thumb: you almost always want to use vocabulary. Perl Best Practices by Damian Conway bluntly: " Never make variables part of the module interface " (emphasis in the original).

+7
source

You should read Copy using Scoping "MJD.

perldoc perlmod will also be useful to read.

The code comes out of this world ugly. It tramples on all kinds of namespaces without concern in the world just because the author seems to think that $ author :: email is cool.

It would be best to use a hash:

 my %author = ( email => ' author@example.com ', ... ); 

Tumbling throughout the character table is not required.

I have some examples of Win32::OLE : http://www.unur.com/comp/ which are not works of art, but I believe that the improvements are in this style. See also Why the number of pages in a Word document is different Perl and Word VBA?

I'm going to tell a little:

 @pgm::runtime_args = @ARGV ; 

So, we are abandoning the standard @ARGV array to trample the pgm namespace. Not only that, every Perl programmer knows what @ARGV . Anyway, @pgm::runtime_args not used again in the script.

 $pgm::maxargs = $#pgm::runtime_args + 1 ; 

Of course, @pgm::runtime_args in a scalar context will give us the number of elements in this array. I have no idea why $pgm::maxargs might be needed, but if so, then this line should have been:

 $pgm::maxargs = @pgm::runtime_args; 

I do not quote this material anymore. This is probably what happens when Cobol programmers try to write Perl.

 $program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved."; 

I am glad that he allocated five figures for the year. I never know!

PS: I believe my excerpts are fair use.

+8
source

Package variables are global variables; they are visible throughout the entire program (even other modules). They are useful when you want or need such a level of visibility and / or external influence. For example, the Text :: Wrap module uses them to resolve a single configuration point for the number of columns on which to wrap text. Moreover, the package variables allow you to use something called "dynamic scaling", but this is a somewhat advanced and slightly esoteric concept.

For your second question, see What is the difference between mine and ours in Perl?

+4
source

Source: https://habr.com/ru/post/1286486/


All Articles