Re: Basic mod-perl question : why my variable is undefined ?
by kennethk (Abbot) on Jul 23, 2014 at 15:04 UTC
|
Variable "$lig" will not stay shared
You have scoping problems with your closure. That warning will be issued by code like
sub one {
my $x;
sub two {
print $x;
}
}
Since mod_perl compiles all your scripts into a dispatch table (as I understand it), it seems plausible to me that the copy of $lig referenced in your compiled copy of xxx() is not the lexically-scoped variable you are working with after your script executes a couple times.
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
|
|
Yes you are right, "I" am exactly in this case, as mod_perl includes (automatically) my full script in a sub. So maybe it is my understanding of what is a "closure" or what is "lexically-scoped" which is bad.
I would have thought that as $x is defined in sub one, its scope goes until the end of sub one. I suppose I am wrong..? Why ? And is there a way to have a variable common to one and two, but declared inside one, as with mod_perl I have no access (at my knowledge) outside one... ?
| [reply] |
|
|
The problem with the demo code is that each subroutine is only compiled once. That means that the $x variable in two corresponds to the $x variable in the first call of one. The first instance of $x persists as there is a reference to it stored in two.
Solutions include explicitly passing the value, forcing recompile each time through using a code reference (sub), swapping $x to a constant... What is the reason you aren't just passing in the value of $lig?
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Basic mod-perl question : why my variable is undefined ?
by Anonymous Monk on Jul 23, 2014 at 11:00 UTC
|
Main( @ARGV );
exit( 0 );
sub Main {
my $lig = 4;
my $q = CGI->new;
DoSomething( $lig, $q );
}
sub DoSomething {
my( $lig, $q ) = @_;
...
}
Also, Basic debugging checklist , brian's Guide to Solving Any Perl Problem, CGI Help Guide , Troubleshooting Perl CGI scripts, CGI to mod_perl Porting. mod_perl Coding guidelines
Tutorials: Variable Scoping in Perl: the basics, Coping with Scoping , Mini-Tutorial: Perl's Memory Management, Lexical scoping like a fox, Read this if you want to cut your development time in half!, Closure on Closures , perlref#Circular References, Memory leaks and circular references, Circular references and Garbage collection., make perl release memory, about memory management , Re^3: Scope of lexical variables in the main script , Re: What's the weaken here for?, Devel::Cycle, Devel::NYTProf, Devel::Leak Devel::LeakTrace, WeakRef
Basic debugging checklist and brian's Guide to Solving Any Perl Problem ) ... On debugging, verify everything, talk to teddybear ... checklists and more, Re^3: A Beginner Needs Homework help | [reply] [d/l] |
|
|
Thenk you,
1- You give me very muche reading. Thank you. I have read most of that many times and I am lost in it, and this is the reason that I ask.
2- OK, I know that there are problems with global variable. Sure I can declare $lig in the sub. But my question is generic : why it does not work ?
| [reply] |
Re: Basic mod-perl question : why my variable is undefined ?
by AnomalousMonk (Archbishop) on Jul 23, 2014 at 13:51 UTC
|
c:\@Work\Perl\monks>perl -wMstrict -le
"my $x;
;;
S('A');
;;
$x = 'foo';
;;
S('B');
;;
sub S { print qq{$_[0]: x is }, defined $x ? qq{'$x'} : 'undefined';
+}
"
A: x is undefined
B: x is 'foo'
This simple example code always produces the output shown. It's easy to imagine that in your "much more complex" code different execution paths are sometimes taken, such that your equivalent of $x has, on occasion, already been initialized when subroutine S() is called at point 'A'. In any event, I hope it is clear why $x is uninitialized at point 'A' and initialized at point 'B'.
Update: See also the discussion in response to subroutine no error.
| [reply] [d/l] [select] |
|
|
Thank you. This is clear, but it is not my problem. And this is not mod-perl. The point is "sometimes", not "always".
| [reply] |
Re: Basic mod-perl question : why my variable is undefined ?
by kcott (Archbishop) on Jul 23, 2014 at 11:33 UTC
|
#!/usr/bin/env perl
use strict;
use warnings;
my $lig;
#...
$lig=4;
print STDERR "ligA <<$lig>>\n";
sub xxxx
{
#...
print STDERR "ligX <<$lig>>\n";
}
print STDERR "ligB <<$lig>>\n";
xxxx();
Outputs:
ligA <<4>>
ligB <<4>>
ligX <<4>>
[I'm running 5.18.1 on darwin-thread-multi-2level]
| [reply] [d/l] [select] |
|
|
Thank you. Did you try under mod-perl ?
Anyway, my script is much more complex. And sometimes the result is ok. Other times it is not.
| [reply] |
Re: Basic mod-perl question : why my variable is undefined ?
by hippo (Archbishop) on Jul 23, 2014 at 12:15 UTC
|
Your reported output lgeX <<>> does not match any of the I/O lines in your provided code. Are you perhaps confusing the $lig variable with something else?
Why is $lig a variable if you never change its value? Why not declare it as a constant instead? If its value does change (from 4) why have you not shown that code?
Update note: The OP has now removed the reference in the parent node to "lgeX" in the output.
| [reply] [d/l] [select] |
|
|
Thank you. Well, there is no mistake. You see lgeX<<>> because $lig is not correct and seems to be undef.
I have simplified the code. In fact $lig is incremented in xxxx().
| [reply] |
|
|
| [reply] |
|
|
Re: Basic mod-perl question : why my variable is undefined ?
by locked_user sundialsvc4 (Abbot) on Jul 23, 2014 at 11:03 UTC
|
Well, first of all, the usual questions ... do you have use strict; use warnings; and in that situation does it “compile cleanly?”
Next, well, there is no such thing as “sometimes, not always.” What you are dealing with here is a bug ... in your code. Somewhere. That bug is probably located in the bit of code that you elided out, the second time, with "...". I do not believe that this has anything in particular to do either with mod_perl nor the Registry.
In addition, I suggest that you should put all your code together, in subroutines, and not put subroutines in-the-middle. Let the code-paths be obvious, and contiguous.
| |
|
|
Thank you. Well, I fear that you answer without knowing mod_perl. I suggest you read that http://perl.apache.org/docs/1.0/guide/porting.html#Exposing_Apache__Registry_secrets
| [reply] |