This is PerlMonks "Mobile"

Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

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

Hello Perl Monks

I am a little perplexed on the expected output that seems to be effecting me. I have attached a code smippit.

When the script runs, menu option of 16 items will display. If a selection is made between 1-16, then my "print Array count #2" line displays as expected..16

However, if a selection is made of >16, then print Array count #2" is not displaying correctly. It seems to display the value of $ANS or somehow possibly modifying the array????....but I am not sure.

Just wondering if you can look at it and see where I am going wrong or how it needs to be fixed/addressed

use strict; use warnings; system('cls'); my $SWOS=10; Menu_Main(); sub Menu_Main { my @menu=("","5x & 8x Series", "5x Series", "8x Series","Other"); my @arr = (); my $arrcnt=0; my $MMANS; my $menu=1; my $ANS; #$arr = Text to display, Menu position/selection#, Menu Section, +Numerical Reference $arr[$arrcnt][0] = "First", $arr[$arrcnt][1] = 8, $arr[ +$arrcnt][2] = 1, $arr[$arrcnt][3] = 27, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "5x First", $arr[$arrcnt][1] = 13, $arr[ +$arrcnt][2] = 2, $arr[$arrcnt][3] = 28, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "Second", $arr[$arrcnt][1] = 9, $arr[$ar +rcnt][2] = 1, $arr[$arrcnt][3] = 29, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "Third", $arr[$arrcnt][1] = 10, $arr +[$arrcnt][2] = 1, $arr[$arrcnt][3] = 30, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "8x- Fourth", $arr[$arrcnt][1] = 21, $arr[$a +rrcnt][2] = 3, $arr[$arrcnt][3] = 31, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "5x- Fifth", $arr[$arrcnt][1] = 17, $arr +[$arrcnt][2] = 2, $arr[$arrcnt][3] = 32, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "8x- First", $arr[$arrcnt][1] = 18, $arr +[$arrcnt][2] = 3, $arr[$arrcnt][3] = 33, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "8x- Second", $arr[$arrcnt][1] = 19, $arr[$a +rrcnt][2] = 3, $arr[$arrcnt][3] = 34, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "5x- Fourth", $arr[$arrcnt][1] = 16, $arr[$a +rrcnt][2] = 2, $arr[$arrcnt][3] = 35, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "8x- Third", $arr[$arrcnt][1] = 20, $arr +[$arrcnt][2] = 3, $arr[$arrcnt][3] = 36, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "5x- Second", $arr[$arrcnt][1] = 14, $arr[$a +rrcnt][2] = 2, $arr[$arrcnt][3] = 37, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "XXX- First", $arr[$arrcnt][1] = 23, $arr[$a +rrcnt][2] = 4, $arr[$arrcnt][3] = 38, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "Fouth", $arr[$arrcnt][1] = 11, $arr +[$arrcnt][2] = 1, $arr[$arrcnt][3] = 39, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "Fifth", $arr[$arrcnt][1] = 12, $arr +[$arrcnt][2] = 1, $arr[$arrcnt][3] = 40, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "8x- Fifth", $arr[$arrcnt][1] = 22, $arr +[$arrcnt][2] = 3, $arr[$arrcnt][3] = 41, $arrcnt++, if ($SWOS ==10); $arr[$arrcnt][0] = "5x- Third", $arr[$arrcnt][1] = 15, $arr +[$arrcnt][2] = 2, $arr[$arrcnt][3] = 42, $arrcnt++, if ($SWOS ==10); + @arr = sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] } @arr; print "Select [1-" . ($#arr+1) . "].\n"; print "\n$menu[$menu]\n"; for (my $i=0; $i<=$#arr; $i++) { if ($arr[$i][2] != $menu) { print"\t\t-------------------------------------------------- +--------\n"; print "$menu[$arr[$i][2]]\n"; $menu=$arr[$i][2]; } #print "\t\t$arr[$i][1]. $arr[$i][0]\n"; print "\t\t" . ($i+1) . ". " . $arr[$i][0] . "\n"; } print "Selection ==> "; $ANS=<STDIN>; chomp $ANS; print "Array count #1: " . ($#arr+1) . " \n"; # Print elements in +array print "Processing ANS: $ANS\n"; $MMANS=$arr[($ANS-1)][3]; print "Array count #2: " . ($#arr+1) . " \n"; # Print Elements in +array again print "MMANS is: $MMANS\n"; }
Within Menu Range Selection ==> 8 Array count #1: 16 Processing ANS: 8 Array count #2: 16 MMANS is: 42 Outside of Menu Range Selection ==> 30 Array count #1: 16 Processing ANS: 30 Array count #2: 30 Use of uninitialized value $MMANS in concatenation (.) or string at C: +\temp\array.pl line 57, <STDIN> line 1. MMANS is:

Replies are listed 'Best First'.
Re: Count of element in array - autovivification
by 1nickt (Canon) on Feb 22, 2021 at 00:21 UTC

    Hi,

    This line:

    $MMANS=$arr[($ANS-1)][3];
    is populating the array with a new element $arr[($ANS-1)] if it doesn't exist. See autovivification.

    I would suggest validating your input and disallowing a value greater than the number of elements in your array.

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Count of element in array - Help
by jwkrahn (Abbot) on Feb 22, 2021 at 04:33 UTC

    For what it's worth, I made the code more Perlish and incorporated the fix proposed by the others:

    use strict; use warnings; system 'cls'; Menu_Main( 10 ); sub Menu_Main { my ( $SWOS ) = @_; #$arr = Text to display, Menu position/selection#, Menu Section, +Numerical Reference my @arr = sort { $a->[ 1 ] <=> $b->[ 1 ] || $a->[ 2 ] <=> $b->[ 2 +] } $SWOS == 10 ? [ 'First', 8, 1, 27 ] : (), $SWOS == 10 ? [ '5x First', 13, 2, 28 ] : (), $SWOS == 10 ? [ 'Second', 9, 1, 29 ] : (), $SWOS == 10 ? [ 'Third', 10, 1, 30 ] : (), $SWOS == 10 ? [ '8x- Fourth', 21, 3, 31 ] : (), $SWOS == 10 ? [ '5x- Fifth', 17, 2, 32 ] : (), $SWOS == 10 ? [ '8x- First', 18, 3, 33 ] : (), $SWOS == 10 ? [ '8x- Second', 19, 3, 34 ] : (), $SWOS == 10 ? [ '5x- Fourth', 16, 2, 35 ] : (), $SWOS == 10 ? [ '8x- Third', 20, 3, 36 ] : (), $SWOS == 10 ? [ '5x- Second', 14, 2, 37 ] : (), $SWOS == 10 ? [ 'XXX- First', 23, 4, 38 ] : (), $SWOS == 10 ? [ 'Fouth', 11, 1, 39 ] : (), $SWOS == 10 ? [ 'Fifth', 12, 1, 40 ] : (), $SWOS == 10 ? [ '8x- Fifth', 22, 3, 41 ] : (), $SWOS == 10 ? [ '5x- Third', 15, 2, 42 ] : (); my @menu = ( '', '5x & 8x Series', '5x Series', '8x Series', 'Othe +r' ); my $menuidx = 1; print 'Select [1-' . @arr . "].\n\n$menu[$menuidx]\n"; for my $i ( 0 .. $#arr ) { if ( $arr[ $i ][ 2 ] != $menuidx ) { print "\t\t", '-' x 58, "\n$menu[$arr[$i][2]]\n"; $menu = $arr[ $i ][ 2 ]; } #print "\t\t$arr[$i][1]. $arr[$i][0]\n"; print "\t\t", $i + 1, ". $arr[$i][0]\n"; } print 'Selection ==> '; chomp( my $ANS = <STDIN> ); if ( $ANS < 1 || $ANS > @arr ) { warn "$ANS is not a valid menu selection.\n"; return; } # Print elements in array print 'Array count #1: ' . @arr . " \nProcessing ANS: $ANS\n"; my $MMANS = $arr[ $ANS - 1 ][ 3 ]; # Print Elements in array again print 'Array count #2: ' . @arr . " \nMMANS is: $MMANS\n"; }
Re: Count of element in array - Help
by LanX (Saint) on Feb 22, 2021 at 00:19 UTC
Re: Count of element in array - Help
by LanX (Saint) on Feb 22, 2021 at 00:04 UTC
    TL;DR, sorry

    And I don't know if it'll fix your problem ...

    ... but what's catching my eye is code like

        $arr[$arrcnt][0] = "First",            $arr[$arrcnt][1] = 8, $arr[$arrcnt][2] = 1, $arr[$arrcnt][3] = 27, $arrcnt++, if ($SWOS ==10);

    Using the scalar comma operator do separate many expressions means asking for trouble with precedence ( did you even spot the comma before the if )?

    Use semicolon as separator and a good old

    if ($SWOS ==10) { ... }

    For god's sake just write something like

    @arr = ( ["First", 8, 1, 27], ["5x First",... ], ... #etc );

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: Count of element in array - Help
by AnomalousMonk (Archbishop) on Feb 23, 2021 at 00:37 UTC

    Looking at the dismaying initialization of the @arr array in the OP, I think it might be helpful to provide a link to the Perl Data Structures Cookbook (perldsc), even if it's a bit late.


    Give a man a fish:  <%-{-{-{-<

Re: Count of element in array - Help
by g_speran (Scribe) on Feb 22, 2021 at 00:41 UTC
    Thanks for the replies. After walking away i thought about using DataDumper to view the contents of the array and indeed I verified, as y'all have done that the $MMANS was manipulating the array size. Thanks for the responses
    $VAR17 = undef; $VAR18 = undef; $VAR19 = undef; $VAR20 = undef; $VAR21 = undef; $VAR22 = undef; $VAR23 = undef; $VAR24 = undef; $VAR25 = undef; $VAR26 = undef; $VAR27 = undef; $VAR28 = undef; $VAR29 = undef; $VAR30 = undef; $VAR31 = [];