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

I am working with CGI.pm, and am having difficulties getting things to work, it may be a basic perl issue, or it may be something specific to CGI.pm. Here's what I am doing.

I want to use popup_menu to generate an HTML select. I can get this code to work just fine:

print $CGI->popup_menu(-name=>'menu_name', -values=>{'one'=>'eenie', 'two'=>'meenie', 'three'=>'minie'});

(where $CGI was created earlier with $CGI = new CGI;)

This works fine, so now I want to make the hash literal a has variable, so I try this:

%menu_values = {'eenie'=>'one', 'meenie'=>'two', 'minie'=>'three'}; print $CGI->popup_menu(-name=>'menu_name', -values=>%menu_values);

But what gets generated is this:

<select name="menu_name" > <option value="HASH(0x40132724)">HASH(0x40132724)</option> </select>

Huh? So I turn to my perl book "Learning Perl" published by O'Reilly, and see that it has hash literals in parens. Curious, but I try that, change my {} to (). But, now this is generated:

 <select name="menu_name" three="meenie" one="minie" two> <option value="eenie">eenie</option> </select>

and I'm surprised that my browser even accepts it, but its not right. Please, what am I doing wrong?

Edit: g0n - code tags

Replies are listed 'Best First'.
Re: popup_menu CGI.pm problems
by liverpole (Monsignor) on Jan 19, 2007 at 16:19 UTC
    Hi kmullin5016,

    Try this:

    + use strict; use warnings; use CGI; + my $CGI = new CGI; + my $menu_values = {'one' => 'eenie', 'two' => 'meenie', 'three' => 'mi +nie'}; + print $CGI->popup_menu(-name=>'menu_name', -values=>$menu_values);

    If you had used strict and warnings in your code, you would have seen the error:

    Reference found where even-sized list expected at test.pl line 18.

    which might have tipped you off that your were trying to assign a hash reference to a hash.

    When you use parentheses ( ... ), it's a plain hash; when you use braces { ... } it's a hash reference (like a pointer to a hash).

    Use the latter, and it produces the same output as in your first example which you said "works fine".

    Oh, and you apparently had your arguments backward in the hash.  I just reversed the order ('eenie' => 'one' becomes 'one' => 'eenie'), and got the output that you said was correct (ie. the same as print $CGI->popup_menu(-name=>'menu_name', -values=>{'one'=>'eenie', 'two'=>'meenie', 'three'=>'minie'});):

    <select name="menu_name"> <option value="three">minie</option> <option value="one">eenie</option> <option value="two">meenie</option>

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: popup_menu CGI.pm problems
by kyle (Abbot) on Jan 19, 2007 at 16:13 UTC

    You should:

    %menu_values = ('eenie'=>'one', 'meenie'=>'two', 'minie'=>'three'); print $CGI->popup_menu(-name=>'menu_name', -values=>\%menu_values);

    The {a => 1} syntax makes a hash reference (anonymously). The \%menu_values makes a reference to the named hash %menu_values. See also perldata for more about hashes, and perlreftut and perlref for more about references.

Re: popup_menu CGI.pm problems
by davorg (Chancellor) on Jan 19, 2007 at 16:15 UTC
    %menu_values = {'eenie'=>'one', 'meenie'=>'two', 'minie'=>'three'};

    You have the wrong kind of brackets in that assignment. Hashes are initialised from lists, so you should have ( ... ) (round brackets), not { ... } (curly brackets).

    If you had use warnings in your code, then you would have seen the error "Reference found where even-sized list expected" - which might have been helpful to you.

    Oh, and then you need to pass a _reference_ to the hash into the function.

    print $CGI->popup_menu(-name => 'menu_name', -values => \%menu_values);
    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: popup_menu CGI.pm problems
by kmullin5016 (Acolyte) on Jan 19, 2007 at 17:46 UTC

    Thanks, the ino on the reference got my simple example working. Now I'm working on the more complex version where I have:

    %OS_APP_NAME = (
            'AA'  => 'HP-UX',
            'AB'  => 'SunOS',
            'AD'  => 'Linux',
            'AJ'  => 'Windows 2000',
            'AK'  => 'Apache',
            'AM'  => 'IIS',
            'AP'  => 'VMware',
            'AR'  => 'Windows 2003',
            'E'   => 'AIX',
            'MC'  => 'ControlM',
            'QD'  => 'DYNIX',
            'X'   => 'Tandem'
    );
    

    to create the hash, and this to use it:

     $CGI->popup_menu(-name=>'TECH_SPEC_ID',
                      -values=>\%OS_APP_NAME);
    

    When I run this, it does not generate a select at all, and I get no errors from PERL. In the perl debugger, I can stop it on this line and print the hash to verify it was built properly. Does anybody see a problem?

      $CGI->popup_menu returns a string that you have to print yourself. This seems to work when I run it:

      #!/usr/bin/perl -w use CGI; my $CGI = CGI->new(); %OS_APP_NAME = ( 'AA' => 'HP-UX', 'AB' => 'SunOS', 'AD' => 'Linux', 'AJ' => 'Windows 2000', 'AK' => 'Apache', 'AM' => 'IIS', 'AP' => 'VMware', 'AR' => 'Windows 2003', 'E' => 'AIX', 'MC' => 'ControlM', 'QD' => 'DYNIX', 'X' => 'Tandem' ); print $CGI->popup_menu(-name=>'TECH_SPEC_ID', -values=>\%OS_APP_NAME);

      If the missing print is not the problem, I don't know what is.

      Thanks for being my 2nd pair of eyes. I added the print (duh!)
        OK, on the same lines, I notice that the order of the options is random, and on of my books says that, but the CGI doc contained in perl doc format in the CGI.pm module itself doesn't.

        I'm thinking that if I give it an ARRAY reference for the -values parameter, the order will be the same as in the array, and they I can give it a hash in the -labels parameter to contain the actual values I want my select to return to the CGI when a user selects a value.

        I try that with the following code:

        %menu_labels = ('one'=>'eenie',
                        'two'=>'meenie',
                        'three'=>'minie');
        @menu_values = ('eenie', 'meenie', 'minie');
        print $CGI->popup_menu(-name=>'menu_name',
                    -values=>\@menu_values\,
                    -labels=>\%menu_labels);
        

        which generates:

        <select name="menu_name">
        <option value="eenie">eenie</option>
        <option value="meenie">meenie</option>
        <option value="minie">minie</option>
        </select>
        

        which is close, the order is determined by the array, but I don't have the values from my label parameter (the hash). So again, what am I doning wrong. I'm frustrated because I'm finding incomplete/contradictory information in my book (Learning Perl by O'Reilly))and the Perl doc from CGI.pm.

        A reply falls below the community's threshold of quality. You may see it by logging in.