Spenser has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a project for work and I have been using the  Near the top of my scripts, I put the following lines, among others:

use CGI qw/: standard/; my $q = new CGI;

This allows me to do lines like this:

print $q->redirect(-location=> "otherscript.cgi?ord_id=$ord_id");

However, I have been running into some problems with passing data from one script to the next (i.e., order numbers).  If the script that has the line "new CGI" sends data to another script that also has "new CGI", the data seems to get wiped out by that line in the second script.  I tried modifying the line in the second script to read just:

my $q = CGI;

That solved the passing problem, but it seemed to make the other "print $q->" type lines a little flat or they did odd things.  I know, I'm being vague, but I'm recalling symptoms from frustrating moments.  I tried alternating between "new" and not "new", but that doesn't always work.  I'm just running around in circles putting out fires and starting other ones.

In summary, I don't know what "my $q = new CGI;" does.  Therefore, I don't know when to use it and how to modify it.  Can someone explain to me the concepts behind it so I'll know what to do, please?  Thanks.

Replies are listed 'Best First'.
(zdog) Re: Conceptualizing
by zdog (Priest) on Dec 16, 2001 at 05:30 UTC
    I'm not very good with OO terminology so I am not going to try to explain. However, under normal circustances, one will not do "use CGI qw(:standard);" and "my $q = new CGI;" at the same time. Both provide you with an interface for accessing CGI parameters, but go about it a little differently. With the example you have above, you could do this:
    use CGI; my $q = new CGI; my $value = $q->param ('ord_id');
    The param function assciated with the CGI object $q returns the value of the parameter passed to the script, so now $value contains whatever the order id was. The following does the same thing:
    use CGI qw (:standard); my $value = param ('ord_id');
    Except this time, param is no longer associated with an object and can be treated like any regular sub. Hope that helps at least a bit.

    Zenon Zabinski | zdog |

Re: Conceptualizing
by chromatic (Archbishop) on Dec 16, 2001 at 07:20 UTC
    I'm confused by some of your terminology. When you say you have scripts, do you mean that each is invoked by a separate user request? Or are you using do or require or some other method to accomplish things in the same request?

    If the former (which I suspect to be the case), you may not be getting the data because you're not passing it as form or query string parameters. Just a guess, though your redirect appears to be okay.

    To explain the new() call, you have to know a little bit about object oriented programming. An object is a bundle of data that has associated behavior. That's it. The data, in this case, is the data from the user request. The behavior are subroutines like redirect() and param().

    When you call new(), the CGI module grabs the data and performs a little magic to make an object, then returns that to you. If you call new() again within the same process, you'll run into trouble -- the existing data has been used up to create the first object.

    Does that make more sense? That's why I'm a little confused by your terminology.

      I probably should be ashamed to say this, but I tend to use the words script and program interchangably.  However, I think that the word script is appropriate here as you're (chromatic) implying:  Each of my .cgi files have minimal functions (keeping with Unix Philosophy).  Some create a web page for displaying a "form" for the user to fill out and "submit" for "post"ing.  Some read in data from previous scripts (via and HTML forms and some parsing I ripped off from O'Reilly--subparseform.lib) and process the data (e.g., update a mySQL database).  I do have some "require" lines that call upon a couple library (.lib) files that contain common functions.  Maybe these are causing me trouble.

      Alright, now we're getting complicated and getting involved too much in fixing my immediate problem, which isn't as important for me as my grasping the concept of "new CGI" (and I guess from what you're telling me, object oriented programming).  Grasping the concept, I believe, will solve the immediate problem and future ones.

      You mentioned that if I call new() within the same process, I'll run into trouble.  This seems to be the effect (the trouble, that is) that I'm experiencing.  It also seems to be touching on the subtle conceptual aspect that I was suspecting:  namely, although I may use new() in two separate .cgi files, by passing data from one to the other in this object bundle, as you put it, or $q, as I coded it, am I wiping out the data within $q with another new() in the second script by invoking it before I can parse the data into my string variables?  Boy, that was a long-winded question.  Put simply, if I were to alternate from $q and $x, or if I were to not declare new() until after I parse and save my data into string variables, would that solve my problem?  Okay, another long-winded sentence--it seems unavoidable for me when discussing such a concept and trying to apply it.  I'll stop here and let you and others respond, if you all would be so kind.

      Oh, and thanks for all of the postings thus far.  They have been helpful.  I've been playing with the practical suggestions and pondering the conceptual ones.  I think I'm getting closer.  Of course, that may yet to be determined.

Re: Conceptualizing
by kwoff (Friar) on Dec 16, 2001 at 05:51 UTC
    This is what happens when you don't `use strict`. :P

    I think you're probably jumping to the wrong conclusions about what's causing what. I understand the frustration, but it's also hard to tell what the cause is. I personally abhor the :standard pragma and religiously use the object-oriented interface. If you only need certain functions, note that you can call things using something like CGI->redirect(...) without creating a new object.

Re: Conceptualizing
by guha (Priest) on Dec 17, 2001 at 00:28 UTC
    I have not tested this but AFAIK when you want to access parameter off the URL you should use the url_param() method

    This applies to your otherscript.cgi where you would initialize a new CGI-object and then access the parameter like this

    use CGI; my $q = new CGI; my $ord_id = $q->url_param('ord_id');
    Using use CGI qw/: standard/; instead of use CGI; gives you a "magic/invisible" object which you in fact can access as $CGI::Q making the code snippet above look something like
    use CGI qw/: standard/; my $ord_id = url_param('ord_id');
    So choose one, not both!