"John D. Leonard II" wrote:
>
> All:
>
> *** BE CAREFUL ***
>
> Examine the following code from a single ASP script:
>
I really need to clarify this. You have identified a problem
that relates to perl & mod_perl, but this is not a problem
with using globals. Rather a problem of have a subroutine
compiled using a my variable of a different scope. This
value becomes sticky for the life of the subroutine compilation
which is why I suggested to NOT put subroutines in your
ASP script. This is not a problem of global, but of my() scoped
closure & subroutine compilation.
This problem is described well here:
http://perl.apache.org/guide/perl.html#my_Scoped_Variable_in_Nested_S
To use globals safely, do a use vars() declaration. my()
declarations are fundamentally not global declarations.
Here's an example of a useful global use in a Apache::ASP
application:
# global.asa
use Apache::DBI;
use vars qw($Db);
sub Script_OnStart {
$Db = DBI->connect(...);
}
Now $Db, your database connection will be available
in all your scripts just like $Server, $Session, etc,
and its for setting up these kinds of globals that I would
recommend global. I would not set it just to get data
from a script into an include, though I might find a
global $App object or a %Vars type data structure convenient
for passing data around.
> The subroutine "Mylocalsub" simply returns a variable originally set in the
> main script. One (at least naive me!) naturally assumed that Mylocalsub
Its a common mistake, and unfortunately not picked up by use
strict. There are actually time when you want this in perl
programming I guess, as I have done before, with defining anonymous
subs on the fly:
my $val = 1;
my $sub = sub{ $val }
my $newval = &$sub;
It can be awful nice to have the context at compilation time
to have the my() content visible to the compilation. Now why
should this be true for named subs as well? The only reason I
can imagine is it makes my() scoped vars in packages available
as static globals, which cannot be changed from outside the
package. One could look at these as true private globals,
so seem useful as well when developing a perl module.
>
> Because of how the scripts gets compiled (and how DynamicIncludes is set),
> $Response->Include behaves the same as above. I do not think that it is
> wise to write code dependent on the setting of DynamicIncludes.
>
This has nothing to do with DynamicIncludes. DynamicIncludes should
even protect you from this, since these includes will not share
a my() scoped var from your script by accident, since they are not
compiled in that script. A sub in an inline include could have this
property, but not in a DynamicInclude.
As an example:
# script.asp
<% use strict; my $var = 1; %>
<% $Response->Include('hi.inc'); %>
# hi.inc
<% use strict; %>
<%= $var %>
This will get a compilation error because $var is not declared
in hi.inc. If use strict; were not set ( use UseStrict setting
for ASP programming ), $var would just be undef, and the output
of this would just be some white space probably.
> One possible fix:
> <%
> $Response->write( &Mylocalsub($mainvariable) );
> #with appropriate fixes to Mylocalsub still required.
>
> or
>
> $Response->Include( "mylocalsub.inc", $mainvariable ); #if using Includes!
>
> %>
>
> The lesson:
>
> DO NOT DEPEND ON GLOBAL VARIABLES. ALWAYS PASS DATA TO SUBROUTINES VIA AN
> ARGUMENT LIST. (Or set appropriate variables in the "Script_OnStart" or
> store important stuff in the $Session.)
>
No. Rather, do not use my() variables as globals and do not define
subroutines in an ASP script, but define those subs in global.asa or
a regular perl package.
--Josh
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]