You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Steve Bannerman <st...@comlab.ox.ac.uk> on 2003/08/08 05:56:46 UTC

RE: HTTP POST: parameters "empty" when usingModPerl::Registry(okay when using ModPerl:PerlRun)...

Perrin,

Thanks...your explanation makes sense.

I was thinking of the subroutine as a method on a class and that the objects
in the class had a cgi instance associated with them.  I was thinking in the
object paradigm rather than in the procedural paradigm.

Cheers
--
   Steve Bannerman
   steve.bannerman@comlab.ox.ac.uk
   44.(0)1865.273866


> -----Original Message-----
> From: Perrin Harkins [mailto:perrin@elem.com]
> Sent: 07 August 2003 19:10
> To: steve.bannerman@comlab.ox.ac.uk
> Cc: modperl@perl.apache.org
> Subject: RE: HTTP POST: parameters "empty" when
> usingModPerl::Registry(okay when using ModPerl:PerlRun)...
>
>
> 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


RE: HTTP POST: parameters "empty" when usingModPerl::Registry(okay when using ModPerl:PerlRun)...

Posted by Perrin Harkins <pe...@elem.com>.
On Thu, 2003-08-07 at 23:56, Steve Bannerman wrote:
> I was thinking of the subroutine as a method on a class and that the objects
> in the class had a cgi instance associated with them.

That's a good way of doing things, but you would have to structure your
code a little differently.  If that appeals to you, I recommend you take
a look at CGI::Application.  There's an article about it here:
http://www.perl.com/pub/a/2001/06/05/cgi.html

- Perrin