Transition from CGI to mod_perl. Understanding my, our, local

I have been using apache mod_cgi for several years. Now I move on to mod_perl and I found some problems, especially with routines. So far, I have never used my , our and local ; and CGI scripts worked without problems. After reading the documentation and even some of the previous questions posted here, I understand more or less how my , our and local . My concern is what information will be passed between the following requests (if I understand correctly that the main problem I should have when running mod_perl instead of mod_cgi).

  • Is there a difference between using our in a scalar or just a scalar without declaring anything special like my ? Not global?
  • If I do not declare that the scalar as private will be used in the next query? Even in another request of another perl script on the same server?
  • How can I share the scalar value inside a subroutine outside this subroutine, but not outside the same file, nor with the same query?
  • If I use my in a scalar inside an if at the same file level or in the same routine, and then create another if , where I use the same scalar; that the scalar shared between if or each if means different blocks? What about while and for , are they different blocks for a previously declared my scalar or does it only work for routines and files?
+6
source share
2 answers

mod_perl works by wrapping every Perl script in a routine called handler inside the package based on the name and path of the script. Instead of starting a new process to run each script, this handler routine is called by one of several constant Perl attacks.

Usually this knowledge will help a lot to understand the changes in the environment from mod_cgi, but since you have never added use strict to your programs and are not familiar with the work of declared variables, you have a lot of catch-up!

The mod_perl environment can cause non-obvious security breaches, and you should now start with use strict on each script and declare each variable. use Carp will also help you understand error logs.

The variable name declared with our is a synonym with a lexical scope for a package variable with the same name that can be used without a full definition of the name, including the package name. For example, usually a variable declared with our $var provides access to the scalar $main::var (if there was no package declaration earlier) without specifying main:: . However, such variables that started life with the undef value in mod_cgi now retain their values ​​from the previous execution of any given mod_perl stream, and for consistency it is most safe to always initialize them at the declaration point. Also note that the default package name is no longer main due to the wrapping that mod_perl does, so you can no longer access package variables using the main:: prefix, and it is not wise to find the actual package name and use it explicitly because it will be a very long name and will change if you move or rename your script.

A my variable is one that exists independently of the package symbol table, and usually its lifetime is the execution time of the attached file (for variables declared in the file area) or subroutine. They are safe in mod_perl if they are declared and used in the scope of the contents of the script file or completely within the same routine, but you can be stung if you scope and declare my $global in the scope of files, and then try to use it in the routine. The reason for this is not simple, but it is because mod_perl wraps your script in the handler routine, so you have subroutine declarations. The internal routine will tend to accept only the first instance of $global and ignore any others created by later handler calls. If you need a global variable, you must declare it with our and initialize it in this declaration, as described above.

A local variable is very similar to our in that it forms a synonym for a package variable. However, it temporarily stores the current value of this variable and provides a new copy for use until the end of the block area or region. Due to its automatic creation and deletion within its scope, it can be a useful alternative to the my variable in mod_perl scripts, especially if you use pointers to data structures, such as an instance of the CGI class. The declaration our $cgi = CGI->new correctly create the object, but due to persistence, mod_perl would leave it in memory until the next execution of the thread removes it to make room for another.

Regarding your questions:

  • Using a variable without declaring it results in a compile-time error if use strict in place, as it should be. Otherwise, it is synonymous with this variable in the current package namespace.

  • Variables are either package variables or lexical variables; there is no way to declare a variable as private as such. Lexical variables (declared using my ) will be created and destroyed each time the script is executed, unless you create an invalid closure, as described above, by writing a subroutine that uses a variable declared in a wider scope when the variable is constant, but will not do what you want. A variable declared with our will retain its value when the script is called, and a variable declared with local will be destroyed when the script ends. Both our and local variables are package variables, and all references to the same variable name refer to the same variable.

  • To declare a variable that is always available everywhere in any script call, you can use the local variable or the initialized our variable. In the file area, local $global is pretty much equivalent to our $global = undef for mod_perl scripts. If you use our variable to point to a data structure, then remember to destroy it at the end of the script with undef $global .

  • my variables are unique and visible inside the block in which they are declared, whether it be a block within if , while or for , or even just the bare { ... } block size. Always use my variables for temporary working variables that are only used inside the block and are accessible from nowhere.

I hope this helps

+17
source

Edit:. This is general information about the visibility of Perl variables. Please see Borodin's post for specific mod_perl problems.

Variables declared with my are lexical. In other words, they exist only within the current volume. You must declare all your variables with my default; just do something else when you specifically want different functionality.

Using lexically-copied variables is an essential part of good code in (almost) any language. Room use strict; and use warnings; all of your scripts will require you to follow this good practice.

our is a way to declare a global variable; the main result is very similar to using undeclared globals. However, this has two differences:

  • You explicitly state that you want the variable to be global. This is good practice since using global variables should be an exceptional case. Because of this, you can create a global this way, even if you use strict; .
  • A variable declared with our will be available by the name that you declare in all packages in the current scope. An undeclared variable, in contrast, is available only by its simple name in the current package. Alternatively, you can only reference it as $package::variable .

See the documentation for our for more details.

local does not create a lexical variable; instead, it is a way to give a global variable a temporary value in the current area. It is mainly used with special Perl built-in (punctuation) variables:

 { local $/; #make the record separator undefined in this scope only. my $file = <FILE>; #read in an entire file at once. } 

You can go far by using my at any time for your variables and using local only for special cases, as shown above.

+8
source

All Articles