Re: CGI.pm param and mod_perl - modperl

This is a discussion on Re: CGI.pm param and mod_perl - modperl ; Brian Gaber wrote: > One thought, my code is written to use the CGI.pm > default object so that I do not have something like $q = new CGI; Could > this be the cuase? Very well could be. Doing ...

+ Reply to Thread
Results 1 to 15 of 15

Thread: Re: CGI.pm param and mod_perl

  1. Re: CGI.pm param and mod_perl

    Brian Gaber wrote:
    > One thought, my code is written to use the CGI.pm
    > default object so that I do not have something like $q = new CGI; Could
    > this be the cuase?


    Very well could be.

    Doing a "$q = new CGI" means that you will get a new CGI object on every
    request, which is what you want. I've never used the function interface of
    CGI.pm like you did in your example so I don't know how CGI.pm handles it behind
    the scenes (whether it creates a new object on each request or not). But if I
    were you, that's probably the first place I'd look.

    Also, just a couple of minor nits to help you out. Instead of "$q = new CGI" do
    "my $q = CGI->new()". First off the "my" means it's a local (lexical) variable.
    Always good to have your vars be local unless you know you'll need something
    else. And "new CGI" is the indirect object syntax for method calls which is
    generally frowned upon since it can lead to problems that are hard to track
    down. "CGI->new()" is alway unambiguous.

    --
    Michael Peters
    Plus Three, LP


  2. RE: CGI.pm param and mod_perl

    Michael,

    Using $q was not successful. Here is what I have done:

    use vars qw($q);

    $q = CGI->new();

    sub print_form {
    my $dept2show = 'A';

    if ( $q->param('deptLtr') ) {
    ($dept2show) = $q->param('deptLtr') =~ /^([a-zA-Z]{1})$/;
    }


    I am running this script simultaneously on two PCs. Sometimes
    $dept2show has the expected value, but often is has the an old value.

    -----Original Message-----
    From: Michael Peters [mailto:mpeters@plusthree.com]
    Sent: Friday, June 13, 2008 2:54 PM
    To: Brian Gaber
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Brian Gaber wrote:
    > One thought, my code is written to use the CGI.pm default object so
    > that I do not have something like $q = new CGI; Could this be the
    > cuase?


    Very well could be.

    Doing a "$q = new CGI" means that you will get a new CGI object on every
    request, which is what you want. I've never used the function interface
    of CGI.pm like you did in your example so I don't know how CGI.pm
    handles it behind the scenes (whether it creates a new object on each
    request or not). But if I were you, that's probably the first place I'd
    look.

    Also, just a couple of minor nits to help you out. Instead of "$q = new
    CGI" do "my $q = CGI->new()". First off the "my" means it's a local
    (lexical) variable.
    Always good to have your vars be local unless you know you'll need
    something else. And "new CGI" is the indirect object syntax for method
    calls which is generally frowned upon since it can lead to problems that
    are hard to track down. "CGI->new()" is alway unambiguous.

    --
    Michael Peters
    Plus Three, LP


  3. Re: CGI.pm param and mod_perl

    Brian Gaber wrote:
    > Using $q was not successful.


    That's because you ignored my advice

    > Here is what I have done:
    >
    > use vars qw($q);


    That makes $q a global. Bad, bad, very bad. Slap yourself on the wrist. Remove
    that "use vars" line.

    > $q = CGI->new();


    Now replace that with

    my $q = CGI->new();

    > sub print_form {
    > my $dept2show = 'A';
    >
    > if ( $q->param('deptLtr') ) {
    > ($dept2show) = $q->param('deptLtr') =~ /^([a-zA-Z]{1})$/;
    > }
    >
    >
    > I am running this script simultaneously on two PCs. Sometimes
    > $dept2show has the expected value, but often is has the an old value.


    This is because Apache is using multiple processes to handle things. Sometimes
    you're hitting a process for the first time, so it creates an new CGI object and
    all is well. But sometimes your request goes back to a process that has already
    loaded and executed this code before, so $q is not a new CGI object.

    --
    Michael Peters
    Plus Three, LP


  4. RE: CGI.pm param and mod_perl

    I just did as you suggested.

    Now in the log I get a

    Variable "$q" will not stay shared at ...

    error from the $q->param('deptLtr') in the subroutine.

    When I read the mod_perl docs they suggest that use vars was one
    approach to fix the "Variable X will not stay shared at" error.

    What is the recommended approach? Pass a reference to $q?

    Thanks

    -----Original Message-----
    From: Michael Peters [mailto:mpeters@plusthree.com]
    Sent: Friday, June 13, 2008 3:21 PM
    To: Brian Gaber
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Brian Gaber wrote:
    > Using $q was not successful.


    That's because you ignored my advice

    > Here is what I have done:
    >
    > use vars qw($q);


    That makes $q a global. Bad, bad, very bad. Slap yourself on the wrist.
    Remove that "use vars" line.

    > $q = CGI->new();


    Now replace that with

    my $q = CGI->new();

    > sub print_form {
    > my $dept2show = 'A';
    >
    > if ( $q->param('deptLtr') ) {
    > ($dept2show) = $q->param('deptLtr') =~ /^([a-zA-Z]{1})$/;
    > }
    >
    >
    > I am running this script simultaneously on two PCs. Sometimes
    > $dept2show has the expected value, but often is has the an old value.


    This is because Apache is using multiple processes to handle things.
    Sometimes you're hitting a process for the first time, so it creates an
    new CGI object and all is well. But sometimes your request goes back to
    a process that has already loaded and executed this code before, so $q
    is not a new CGI object.

    --
    Michael Peters
    Plus Three, LP


  5. Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > When I read the mod_perl docs they suggest that use vars was one
    > approach to fix the "Variable X will not stay shared at" error.


    This makes me think that maybe your problem is something else... but try below.

    > What is the recommended approach? Pass a reference to $q?


    Not a reference, but $q itself (objects are already references, so passing a
    reference to a reference doesn't gain anything). It's a good idea in just about
    all programming languages to avoid globals and pass things around to subroutines
    that need them.

    --
    Michael Peters
    Plus Three, LP


  6. Re: CGI.pm param and mod_perl

    Michael Peters wrote:
    > Brian Gaber wrote:
    >> Using $q was not successful.

    >
    > That's because you ignored my advice
    >
    >> Here is what I have done:
    >>
    >> use vars qw($q);

    >
    > That makes $q a global. Bad, bad, very bad. Slap yourself on the wrist.
    > Remove
    > that "use vars" line.


    I don't see what is so bad about this:

    use vars qw($q);
    $q = CGI->new();

    Even though it's a global variable, you are assigning it a new value,
    CGI->new, each time.

    On the other hand, a subroutine should never use a lexical variable that was
    declared outside of it, at least not in a Registry type script because of
    the nested subroutines. So this is very bad and should trigger a "variable
    will not stay shared" warning:

    my $q = CGI->new;
    sub dostuff {
    print $q->param('foobar');
    }

    I suspect the problem is something else, possibly part of the script that we
    haven't seen.


  7. Re: CGI.pm param and mod_perl

    Dondi Stroma wrote:

    > I don't see what is so bad about this:
    >
    > use vars qw($q);
    > $q = CGI->new();
    >
    > Even though it's a global variable, you are assigning it a new value,
    > CGI->new, each time.


    You're right. I don't normally think about registry scripts since I almost never
    use them. I was thinking he was doing that at the top of a module such that it
    was happening at compile time. But even then my advice wasn't that helpful since
    the assignment would still only happen at compile time.

    > I suspect the problem is something else, possibly part of the script
    > that we haven't seen.


    Yeah, I'm starting to think the same thing. Brian, why don't you print the value
    of the param to the log ("warn" is good for this) for the request (along with
    the SQL that you're generating) so you/we can see what the actual value being
    pulled it.

    --
    Michael Peters
    Plus Three, LP


  8. RE: CGI.pm param and mod_perl

    Michael,

    Here is the log you asked for:

    The value of region is Atlantic
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400
    The value of region is Atlantic
    The value of deptLtr is I
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^I' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is O
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400
    The value of region is Atlantic
    The value of deptLtr is K
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^K' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is F
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is F <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is O <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list

    Thanks.
    -----Original Message-----
    From: Michael Peters [mailto:mpeters@plusthree.com]
    Sent: Friday, June 13, 2008 3:47 PM
    To: Dondi Stroma
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Dondi Stroma wrote:

    > I don't see what is so bad about this:
    >
    > use vars qw($q);
    > $q = CGI->new();
    >
    > Even though it's a global variable, you are assigning it a new value,
    > CGI->new, each time.


    You're right. I don't normally think about registry scripts since I
    almost never use them. I was thinking he was doing that at the top of a
    module such that it was happening at compile time. But even then my
    advice wasn't that helpful since the assignment would still only happen
    at compile time.

    > I suspect the problem is something else, possibly part of the script
    > that we haven't seen.


    Yeah, I'm starting to think the same thing. Brian, why don't you print
    the value of the param to the log ("warn" is good for this) for the
    request (along with the SQL that you're generating) so you/we can see
    what the actual value being pulled it.

    --
    Michael Peters
    Plus Three, LP


  9. Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > Here is the log you asked for:


    We need a little more context than that. For instance I don't see where it
    actually has the fatal error you mentioned from the earlier posts. Also, if you
    could annotate it with what the values of those params "should" be.

    But the most important thing you can do is to reduce the problem down to the
    smallest possible code that still has the fatal error. Not only will it help us
    help you, but 90% of the time when I do that I figure out what the problem was
    on my own.

    --
    Michael Peters
    Plus Three, LP


  10. RE: CGI.pm param and mod_perl

    Sorry, my e-mail client didn't like the line endings of the log. Here
    is the log agin in a more readable format:

    The value of region is Atlantic
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400
    The value of region is Atlantic
    The value of deptLtr is I
    The value of set is 0 SELECT * FROM atlantic_rr WHERE dept REGEXP '^I'
    ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is O
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400
    The value of region is Atlantic
    The value of deptLtr is K
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^K' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is F
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is F <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list
    The value of region is Atlantic
    The value of deptLtr is O <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list

    Thanks.

    -----Original Message-----
    From: Michael Peters [mailto:mpeters@plusthree.com]
    Sent: Friday, June 13, 2008 3:47 PM
    To: Dondi Stroma
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Dondi Stroma wrote:

    > I don't see what is so bad about this:
    >
    > use vars qw($q);
    > $q = CGI->new();
    >
    > Even though it's a global variable, you are assigning it a new value,
    > CGI->new, each time.


    You're right. I don't normally think about registry scripts since I
    almost never use them. I was thinking he was doing that at the top of a
    module such that it was happening at compile time. But even then my
    advice wasn't that helpful since the assignment would still only happen
    at compile time.

    > I suspect the problem is something else, possibly part of the script
    > that we haven't seen.


    Yeah, I'm starting to think the same thing. Brian, why don't you print
    the value of the param to the log ("warn" is good for this) for the
    request (along with the SQL that you're generating) so you/we can see
    what the actual value being pulled it.

    --
    Michael Peters
    Plus Three, LP


  11. RE: CGI.pm param and mod_perl

    Michael,

    The fatal errors from yesterday are fixed. When I run this as a
    cgi-bin it runs fine.

    The HTML code that I am selecting looks like this:





    A






    B

    .... Etc (for each letter of the alphabet)

    The value of region is Atlantic <- GOOD
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400

    The value of region is Atlantic
    The value of deptLtr is I <- GOOD
    The value of set is 0 SELECT * FROM atlantic_rr WHERE dept REGEXP '^I'
    ORDER BY dept, pay_list

    The value of region is Atlantic
    The value of deptLtr is O <- GOOD
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list

    The value of region is Atlantic <- GOOD
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400

    The value of region is Atlantic
    The value of deptLtr is K <- GOOD
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^K' ORDER BY dept, pay_list

    The value of region is Atlantic
    The value of deptLtr is F <- GOOD
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list

    The value of region is Atlantic
    The value of deptLtr is F <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list

    The value of region is Atlantic
    The value of deptLtr is O <- ERROR I selected C
    The value of set is 0
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^O' ORDER BY dept, pay_list


    -----Original Message-----
    From: Michael Peters [mailto:mpeters@plusthree.com]
    Sent: Friday, June 13, 2008 4:21 PM
    To: Brian Gaber
    Cc: Dondi Stroma; modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > Here is the log you asked for:


    We need a little more context than that. For instance I don't see where
    it actually has the fatal error you mentioned from the earlier posts.
    Also, if you could annotate it with what the values of those params
    "should" be.

    But the most important thing you can do is to reduce the problem down to
    the smallest possible code that still has the fatal error. Not only will
    it help us help you, but 90% of the time when I do that I figure out
    what the problem was on my own.

    --
    Michael Peters
    Plus Three, LP


  12. Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > The HTML code that I am selecting looks like this:


    That's not necessary. What does your perl code look like now? Also, try
    printing/warning the value of $$, which is the process ID. I think you'll
    find that the value of your variable stays the same for each process.


  13. RE: CGI.pm param and mod_perl

    Dondi,

    Thanks for the advice. Here is the log output now:

    The value of region is Atlantic for PID: 44538
    The value of set is 0 for PID: 44538
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400

    The value of region is Atlantic for PID: 60132
    The value of deptLtr is G for PID: 60132
    The value of set is 0 for PID: 60132 <- GOOD
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^G' ORDER BY dept, pay_list

    The value of region is Atlantic for PID: 48600
    The value of set is 0 for PID: 48600 <- GOOD
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^A' ORDER BY dept, pay_list
    LIMIT 0, 400

    The value of region is Atlantic for PID: 53446
    The value of deptLtr is F for PID: 53446 <- GOOD
    The value of set is 0 for PID: 53446
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list

    The value of region is Atlantic for PID: 53446
    The value of deptLtr is F for PID: 53446 <- ERROR I clicked on G
    The value of set is 0 for PID: 53446
    SELECT * FROM atlantic_rr WHERE dept REGEXP '^F' ORDER BY dept, pay_list

    This last entry for PID 53446 confirms my suspicion that for
    some reason the CGI.pm query object and thus param('var') is not new on
    every run. Why, I have no idea.

    BTW, when you and Michael talk about logging via [warn] are you
    reffering to a syslog change or some Perl function?

    Thanks.

    Brian

    -----Original Message-----
    From: Dondi Stroma [mailto:dstroma@verizon.net]
    Sent: Friday, June 13, 2008 4:38 PM
    To: Brian Gaber
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > The HTML code that I am selecting looks like this:


    That's not necessary. What does your perl code look like now? Also, try
    printing/warning the value of $$, which is the process ID. I think
    you'll find that the value of your variable stays the same for each
    process.


  14. RE: CGI.pm param and mod_perl

    Here are relevant parts of code:

    use CGI '-autoload';
    use DBI();
    use warnings;
    use strict;

    # Initial declaration and/or population of global script variables

    use vars qw($q);

    $q = CGI->new();

    open(DEBUGLOG, ">> /tmp/mod_perl_debug.txt");
    foreach my $name ( $q->param() ) {
    my $value = $q->param($name);
    print DEBUGLOG "The value of $name is $value for PID: $$\n";
    }

    &print_form();

    sub print_form {
    my $region = $q->param('region');
    my $dept2show = 'A';

    if ( $q->param('deptLtr') ) {
    ($dept2show) = $q->param('deptLtr') =~ /^([a-zA-Z]{1})$/;
    }

    -----Original Message-----
    From: Dondi Stroma [mailto:dstroma@verizon.net]
    Sent: Friday, June 13, 2008 4:38 PM
    To: Brian Gaber
    Cc: modperl@perl.apache.org
    Subject: Re: CGI.pm param and mod_perl

    Brian Gaber wrote:

    > The HTML code that I am selecting looks like this:


    That's not necessary. What does your perl code look like now? Also, try
    printing/warning the value of $$, which is the process ID. I think
    you'll find that the value of your variable stays the same for each
    process.


  15. Re: CGI.pm param and mod_perl

    On Fri, Jun 13, 2008 at 2:53 PM, Michael Peters wrote:
    > Doing a "$q = new CGI" means that you will get a new CGI object on every
    > request, which is what you want. I've never used the function interface of
    > CGI.pm like you did in your example so I don't know how CGI.pm handles it behind
    > the scenes (whether it creates a new object on each request or not).


    Sad to say, CGI->new is mostly just lipstick on a pig. Behind the
    scenes, it still puts everything in globals. CGI.pm is just not an OO
    module.

    However, it is safe to use with mod_perl because it reinitializes the
    globals on each request. The only problems I've run into with this
    are from internal redirects, when it doesn't realize there's a fresh
    request.

    - Perrin


+ Reply to Thread