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

Greetings all,
I have a sub with a couple for loops which are able to print 4 pull down menus just fine from the print statement.
I am having trouble understanding how to return the same 4 pull down menus instead of printing them.
Thanks
Cal
sub getWeekStr{ my ($week1,$week2,$week3,$week4)= @_; my $weekStr; for (my $x = 1;$x <= 4; $x++ ) { my $WEEK_PD = 'WEEK'.$x; my $stored_num = $_[$x-1]; my $WEEK_PD_NAME = 'WEEK'.$x."_PD"; $WEEK_PD_NAME = qq|<SELECT NAME="$WEEK_PD">|; $WEEK_PD =~ s/WEEK//; for (my $y = 1;$y <= 4; $y++){ if ($y =~ /$stored_num/) { $WEEK_PD_NAME .= qq|<option selected value = "$stored_num">TEAM $store +d_num</OPTION>|; } else { $WEEK_PD_NAME .= qq|<option value = "$y">TEAM $y</OPTION>|; } } $WEEK_PD_NAME .= qq|</SELECT>|; print $WEEK_PD_NAME; my $weekStr .= qq|<td align=center width=25%>$WEEK_PD_NAME </td>|; } return $weekStr; }

Replies are listed 'Best First'.
Re: returning values
by fglock (Vicar) on Jul 25, 2003 at 04:55 UTC
    { { # creates $weekStr my $weekStr .= qq|<td align=center width=25%>$WEEK_PD_NAME </t +d>|; } # $weekStr is out of scope. Create a new one return $weekStr; }

    It is easier to catch this if you use strict;

    Update: I see you do use strict. The problem is that you have a second "my" inside the block. It creates a second variable $weekStr. It has the same name, but it is another variable!

      Thanks, I do use strict; Was this a suggestion on how to resolve the problem ?
      #!/usr/local/bin/perl -w use strict; use diagnostics; use CGI qw(:standard);

        As fglock points out, you are shadowing $weekStr with another declaration of it at the end of your first for loop.

        You might reconsider your indentation style. It makes some of those errors easier to spot if you can more easily see what is in a block and what isn't. I recommend using perltidy. I fed your code into it, made one small change¹, and this was the result:

        sub getWeekStr { my ( $week1, $week2, $week3, $week4 ) = @_; my $weekStr; for ( my $x = 1 ; $x <= 4 ; $x++ ) { my $WEEK_PD = 'WEEK' . $x; my $stored_num = $_[ $x - 1 ]; my $WEEK_PD_NAME = 'WEEK' . $x . "_PD"; $WEEK_PD_NAME = qq|<SELECT NAME="$WEEK_PD">|; $WEEK_PD =~ s/WEEK//; for ( my $y = 1 ; $y <= 4 ; $y++ ) { if ( $y =~ /$stored_num/ ) { $WEEK_PD_NAME .= qq|<option selected value = | . qq|"$stored_num">TEAM $stored_num</OP +TION>|; } else { $WEEK_PD_NAME .= qq|<option value = "$y">TEAM $y</OPTI +ON>|; } } $WEEK_PD_NAME .= qq|</SELECT>|; print $WEEK_PD_NAME; my $weekStr .= qq|<td align=center width=25%>$WEEK_PD_NAME </t +d>|; } return $weekStr; }

        I broke up your long qq|| string into two and concatenated them.

        -sauoq
        "My two cents aren't worth a dime.";
        
        fglock's reply was addressed to fixing your problem, but he was misguided in telling you that "use strict;" would help you see the problem.

        The problem is the lexical scoping of "$weekStr" in the bit that fglock copied into his reply. Note that you use  my $weekStr in two different places, and it appears to be the second "declaration" where you manipulate its value. Whatever value is ultimately assigned in that innermost block will be lost when that block goes out of scope.

        Of course, the "strict" pragma is quite content to let you write code like this, even though it may not be in your best interest to do so.

        I would suggest that proper indentation would help a fair bit, and I could also put in a plug for a relevant post of mine, which tries to help locate mistaken uses of "my".

      A million thanks .