how a constructor handle a query string?

I have a class with 2 methods: new and valueOf.

new is supposed to get the query string and decode it into an anonymous hash. The keys for this hash are html form element names (ie., name, address, fav colors, etc), and the values are what the user enters. Has to handle duplicates in the data (fave colors are red and purple).

valueOf gets the name of the form element and returns the value.

i hope i've explained this fully enough. I have NO IDEA how to get the query string into the constructor.

Thanks! Betsy
Who is Participating?
monasConnect With a Mentor Commented:
package Yours;

use CGI;

sub new{
  my $q = new CGI or return {};
  my %ret;

  foreach $k ($q->param){
    $ret{$k} = $q->param($k);

  return %ret;
garfldAuthor Commented:
There must be more to the pm. and, I don't know what you mean by use CGI. If you want to help me you are going to need to spell this out abc. If it's too much trouble - i can understand that, just tell me.

If the keys/values for the hash are from the html form, why would he want a method valueOf to get the name of the form element and returns the value? Why not just process that in the foreach loop?

I am so over my head with this - it shouldn't be that confusing but it is.


      there is module distributed with standard perl distribution. To use it - you should write "use CGI;" as it is spelled in my example. By creating new instance of class CGI you say to get query string and parse it.

      as for valueOf...  you see - hash can hold one and only one value for any key (and there could not be two or more equal keys). Therefore - CGI module in those cases provide array and not a scalar value. valueOf could check is it array and return first item from it in those cases. But then - I have no idea how to get other values with this way constructed API...
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.


What monas is suggesting is:

"Why in the world would you want to write a module to handle CGI transactions, when perl comes with a perfectly good and featureful and very hard to beat module that does the very same thing?"

Possible differing answers are:

i) is too heavy. => Then you could take a look at CGI::Lite
by Gurusam Saratyi.

ii) I want to learn how to write a perl module => That is good, but then you should know about the perl idiom:


and about the relevant documentation that ships with the perl distribution itself.

As for your question "I do I get the query string into the constructor?" the answer is: you don't.
The module you are writing should be able to grab it either from the environment ($ENV{QUERY_STRING)) if GET was used, or from standard input if the method used was POST, in which case your module must know about


So a pseudo-code version (meaning: totally unchecked, even for spelling) of what you appear to want to do is:

package CGI::NewAndBetter;

sub new {
if ($ENV{HTTP_METHOD} eq 'GET') {
#get the query  string out of the environment,
#parse it, and fill a hash with it
} elsif ($ENV{HTTP_METHOD) eq 'PUT') {
#read all the parameters from stdin
#parse them, store them in the hash.
} else {
#complain loudly
 return bless \%theHash

sub valueOf {
 return $$self{$key} if defined $$self{$key};
 return (undef);

You would then import and use your new module as:

use CGI::NewAndBetter;

my $query=new CGI::NewAndBetter;


But unless you are doing it as a purely academic exercise, I would go with - it has been around for what, 5 years now? - and it has grown to a level of sophistication and completeness that cannot probably be matched. It also comes with very good documentation, which does not hurt any.

HTH & cheers,

P.S: if none of this makes any sense to you, then you definitely should get yourself acquainted with the perl documentation, and perhaps with the CGI protocol specs.

garfldAuthor Commented:
this *is* for a class and i am *desperately* trying to understand & write it. i am spinning in circles and burying myself here. i guess i have reached my outer limits here of programming :-) the peter principle? my levels of competency?

anyway, alf, i am rejecting your answer because maybe you or someone else would comment further. your answer is definitely on the right track but i need more details, not just pseudo code. no kidding, i am frantic here.


Let me see if I am digging your position here.

i) You appear to be on your way to write a package to handle CGI intractions in perl;

ii) You do not want to take advantage of prior art in this field;

iii) But you are not motivating (ii)

iv) You appear not to be acquainted with the documentation that comes with perl, with the principles and syntax of OO and modules within perl (and there are hints that some aspects of the Common Gateway Interface are not very clear to you, either);

v) You are giving a rather vague description of your problem;

vi) Yet you seem to expect that someone will come out with a fully coded solution for a task that has not even been clearly stated and motivated.(And may I draw your attention to the fact that it is by sole virtue of the intuition of the forum participants that we even know that CGI is involved here? You never mentioned it, a part from saying you neeed to 'get the query string in a constructor'. Now I'd say we're way removed from a class diagram here.);

And my take on this is:

Yes, you are in over your head on this.

And, I might add, until you revise your attitude towards reading and understanding the basic facts and tools that are relevant to your undertakings, you are doomed to firmly cling to your current position - or, at the very least, to reinvent the wheel.

garfldAuthor Commented:
Alien, I'm learning, is that reinventing the wheel? You don't learn the basics by relying on modules written by other people and not understanding them.

If you think I'm asking for too much help, just don't answer. This is a help forum and your sarcastic comments are not helpful. If I knew all the answers I'd be answering, not asking.

I think you're just annoyed that I rejected your answer - which should have been a comment, by the way, not an answer which blocked anyone else from commenting.

Learning is a *good thing*. In programming, this is most often achieved by reading other people's code (which is how you also achieve understanding). Learning usually does not happen while in a 'frantic' state, to use your word.

You are doing perl code so I assume you have a complete distribution on your disk - it includes a full fledged example ( of what you want to do, and reading it will be a great learning experience. If you feel that that is too complex grab CGI::Lite, which is simpler, off the net and read that.

Neither module will bite you, and you can then adapt the living code to your assignment's task. Of course, anybody could cut and paste the very same code from its editor to the comment window, but that would not be extremely useful, now would it? (I have in my emacs right now, would you like to taste some?)

I could also try and solve your assignment for you with original code. Now why would I bother to do that? I cannot code better perl that Stein or Gurusam (both of which can code my pants off), so it's unlikely I would get world recognition out of that. At the same time you would not learn much either, because, in this process, you would not have perused the Sources Of Wisdom, also known as the docs. (Let me point out to you that your second comment of the thread read, in part "...and, I don't know what you mean by use CGI." . Since "use Foo;" is to a perl programmer  what "#include <stdio.h>" is to a C programmer, doubts are right away cast on your perl proficiency, and doc perusal, by this statement alone.)

Now I would say that reading about the subject you are tackling, write some halfway working code, post it and ask for help would be a more fruitful approach, but who am I to say?

As for being sarcastic, I dunno. Jocularity is more my suit. If icy, bitter sarcasm is what interests you, you should try this thread on comp.lang.perl.misc, but bring your asbestoes in case TomC or Abigail get interested in this.

Cheers, & keep up the good (home)work
OK, Guys, let's go back to constructive discution.

I understand that garfld has program-maximum to become guru of perl and CGI. But to get to this state one need [lot of] time. And experience comes by learning things step-by-step.

So, garfld, what step would you like to take first:

a) learning how CGI programs gets information passwd to them;

b) learning how to program and use perl modules;

c) learning how to put number of values into one "slot" of hash;

d) you name a simple step.

And by the way... Using modules written by others is not so stupid idea... One will never know in depth all the ares, all the nuisances, but thanks to availability of includable parts, one could make use of others knowledge...

And 10 years ago when I was freshmen at university the biggest attention was paid to teach us fundamental things (like fast sorting, memory management, etc). Now things has changed. Now the most important thing is to show students how to use present libraries (think modules in perl) and extend work done by others...
garfldAuthor Commented:
Thanks for a voice of reason. Here's what i need now:

I can write a module and i can write a perl script which creates a new instance of the object and hardcodes the values for that one instance, and i can run that in dos.

Separately, I can write an html form, parse the query string, and use the string. But I can't get it all to work together.

What i just can't get, I can't get from the html form to the constructor and that's where i'm stuck.
OK, post either your last/best try to put things together, or separate working parts what are clear to you, and we will see what will happen...
garfldAuthor Commented:
oh, god - this is the best i could do so far - please don't laugh - do i have to put in that whole thing to parse string? the whole class - all 9 of us - is freaking out & i'm not the only one who can't do it.

package Pizza;
use strict;
   sub new  
      my $class = shift;
      my $newOrder  = {};
      my $newOrder->{toppings} = [];

     if ($ENV{'REQUEST_METHOD'} eq 'GET')
     { @pairs = split(/&/, $ENV{'QUERY_STRING'}); }
     elsif ($ENV{'REQUEST_METHOD'} eq 'POST')
     { read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
     @pairs = split(/&/, $buffer);
     if ($ENV{'QUERY_STRING'})
     { @getpairs = split(/&/, $ENV{'QUERY_STRING'});
     foreach $pair (@pairs)
    ($key, $value) = split (/=/, $pair);
    $key =~ tr/+/ /;
    $key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
     $value =~ tr/+/ /;
     $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
     $value =~s/<!--(.|\n)*-->//g;
     if ($newOrder{$key} )
     {      $newOrder{$key} .= ", $value";       }
     { $newOrder{$key} = $value; }
      bless $newOrder, $class;
      return $newOrder;

     sub valueOf
     my $newOrder    = shift;
     my $item;
    my $top;

     foreach $item {%$newOrder}
     foreach $top {$newOrder->{$toppings}} )
       return $$newOrder{$top};
     return $$newOrder{$item}

#perl script:
 use Pizza;
 $myorder = pizza->new();
 print "Content-type: text/html\n\n";
 print "Thanks for your order, $name<br><br>";
 print "Your order is: ", $myorder->valueOf(), "\n";
 print "\n\n";
garfldAuthor Commented:
ok, i've got it & if anyone wants to see it i'll post it.

alien: we're doing next week :-)
perl -Mdiagnostics 10298135.perl
"my" variable $newOrder masks earlier declaration in same scope at
        line 9 (#1)
    (W) A lexical variable has been redeclared in the same scope, effectively
    eliminating all access to the previous instance.  This is almost always
    a typographical error.  Note that the earlier variable will still exist
    until the end of the scope or until all closure referents to it are
Global symbol "@pairs" requires explicit package name at line 12 (#2)
    (F) You've said "use strict vars", which indicates that all variables
    must either be lexically scoped (using "my"), or explicitly qualified to
    say which package the global variable is in (using "::").
Global symbol "$buffer" requires explicit package name at line 14 (#2)
Global symbol "@getpairs" requires explicit package name at line 18 (#2)
Global symbol "$pair" requires explicit package name at line 23 (#2)
Global symbol "$key" requires explicit package name at line 25 (#2)
Global symbol "$value" requires explicit package name at line 25 (#2)
Global symbol "%newOrder" requires explicit package name at line 32 (#2)
Global symbol "%item" requires explicit package name at line 49 (#2)
garfldAuthor Commented:
I was getting all those errors from the parse-form and didn't know what to do about it. But i took out strict, and took out 'my', and of course, fixed up the parsing to put the values into an anonymous hash and changed the valueOf sub totally... and now it works.

as i said, if anyone's curious, i'll post it. else, thanks anyway!
garfldAuthor Commented:
This is pretty close to the way it worked out & you spent a lot of time with me, you deserve points.

I have to work over this weekend to change it and use :-)

Here's what i ended up with:

package Pizza;
sub new   {
$class = shift;
$newOrder  = {};

            … parse…            
if  ($newOrder->{$key} )  {
$newOrder->{$key} .= ", $value";  }
else {
$newOrder->{$key} = $value; }
bless $newOrder, $class;

return $newOrder;


 sub valueOf       {
 $newOrder = shift;
 $key      = shift;
 return $newOrder->{$key};

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.