On Thu, 2003-08-07 at 03:36, Steve Bannerman wrote: > So with respect to your explanation about the "long running perl system," am > I to understand that the old version of the saveFile() subroutine uses a > reference to a different $cgi instance that the $cgi instance in the main > body of the script?
It uses a reference to the $cgi variable that was in scope when saveFile() was compiled. > As I said, I'm new to perl but that seems to be an awfully strange behavior > of the language...if true, shouldn't the compilation (of the subroutine) > fail because it references an undeclared variable ($cgi)? But it doesn't reference an undeclared variable; it references the original $cgi that was available when the sub was compiled. Closures are a feature of Perl. You can read about them in general in perlfaq7 and the perlref man page: http://www.perldoc.com/perl5.8.0/pod/perlfaq7.html#What's-a-closure- http://www.perldoc.com/perl5.8.0/pod/perlref.html Note that those both talk a lot about anonymous subs, but any sub can be a closure if it refers to a lexical variable defined in an enclosing scope. There is some mod_perl specific stuff on this here: http://perl.apache.org/docs/general/perl_reference/perl_reference.html#my___Scoped_Variable_in_Nested_Subroutines If you had warnings on, you would have received a message about $cgi not staying shared. In brief terms, what happens is that your program creates a lexical called $cgi, then saveFile() refers to it, locking in that variable as the $cgi that will always be referenced by saveFile(). At the end of the script $cgi goes out of scope and disappears, but saveFile() keeps referencing it. In a CGI program this is not a problem, because Perl exits and the process quits. In mod_perl, the code gets run again and saveFile() still refers to the original $cgi. There are a number of ways to solve this problem, but I prefer the one I showed you. Explicitly passing all arguments to subs is well established as a best practice in programming. What you were doing with $cgi before is basically treating it as a global. So, I'd suggest you turn on warnings, turn on strict, and embrace the good practice of passing variables to your subs. - Perrin