Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

I have a list expanding when I don't want it to

by Lady_Aleena (Curate)
on Nov 19, 2014 at 21:26 UTC ( #1107825=perlquestion: print w/replies, xml ) Need Help??
Lady_Aleena has asked for the wisdom of the Perl Monks concerning the following question:

Hello everyone.

In the following function, I create two new keys for a hash which is entered into the function.

use List::Util qw(shuffle); sub random { my ($user_input, $list) = @_; $list->{'all'} = [ map { @$_ } values %{$list} ]; $list->{'keys'} = [ grep {$_ !~ /(?:all|keys)/} keys %{$list} ]; if ($user_input && $user_input =~ /(?:help|options)/) { return 'Your options are: '.join(', ',sort @{$$list{'keys'}}).', o +r all.'; } elsif ($user_input && $user_input =~ /dump/) { use Data::Dumper; return Dumper($list); } else { my $input = $user_input ? $user_input : 'all'; my @random_list = shuffle(@{$$list{$input}}); return $random_list[rand @random_list]; } }

The first time I run a list through random, the list for $list->{'all'} is just what I want it to be. However, upon subsequent runs of random, 'all' grows. I can't figure out why it is doing it. Here is an example...

my %waters = ( running => [qw(spring streamlet rivulet run brook creek stream rive +r)], standing => [qw(drop puddle pool pond lake sea ocean)], precipitation => [qw(rain snow sleet hail)] ); sub random_water { my ($user_water) = @_; random($user_water, \%waters); }

After I run random_waters('dump'), I get...

print random_water('dump'); $VAR1 = { 'keys' => [ 'standing', 'precipitation', 'running' ], 'standing' => [ 'drop', 'puddle', 'pool', 'pond', 'lake', 'sea', 'ocean' ], 'precipitation' => [ 'rain', 'snow', 'sleet', 'hail' ], 'running' => [ 'spring', 'streamlet', 'rivulet', 'run', 'brook', 'creek', 'stream', 'river' ], 'all' => [ 'drop', 'puddle', 'pool', 'pond', 'lake', 'sea', 'ocean', 'rain', 'snow', 'sleet', 'hail', 'spring', 'streamlet', 'rivulet', 'run', 'brook', 'creek', 'stream', 'river' ] };

The hash looks good here, however, when I run it twice...

print random_water('dump'); print random_water('dump'); $VAR1 = { 'keys' => [ 'standing', 'precipitation', 'running' ], 'standing' => [ 'drop', 'puddle', 'pool', 'pond', 'lake', 'sea', 'ocean' ], 'precipitation' => [ 'rain', 'snow', 'sleet', 'hail' ], 'running' => [ 'spring', 'streamlet', 'rivulet', 'run', 'brook', 'creek', 'stream', 'river' ], 'all' => [ 'standing', 'precipitation', 'running', 'drop', 'puddle', 'pool', 'pond', 'lake', 'sea', 'ocean', 'rain', 'snow', 'sleet', 'hail', 'spring', 'streamlet', 'rivulet', 'run', 'brook', 'creek', 'stream', 'river', 'drop', 'puddle', 'pool', 'pond', 'lake', 'sea', 'ocean', 'rain', 'snow', 'sleet', 'hail', 'spring', 'streamlet', 'rivulet', 'run', 'brook', 'creek', 'stream', 'river' ] };

'all' has grown, it even includes the keys, which shouldn't be possible as I create 'keys' after I create 'all'. I can't figure out why. %waters should grow between runs, right?

No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
Lady Aleena

Replies are listed 'Best First'.
Re: I have a list expanding when I don't want it to
by BrowserUk (Pope) on Nov 19, 2014 at 21:41 UTC

    Because this line:

    $list->{'all'} = [ map { @$_ } values %{$list} ]; #...............................^^^^^^^^^^^^^^

    Will get *all* the arrays from %$list including the one from the 'all' key; which will be empty the first time, but will still have everything you put in it the first time, and thus add it all again the second time.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      So, undef before I return or check it for definedness before I fill it?

      Update: I emptied the two keys before I returned, and it seems to work.

      sub random { my ($user_input, $list) = @_; $list->{'all'} = [ map { @$_ } values %{$list} ]; $list->{'keys'} = [ grep {$_ !~ /(?:all|keys)/} keys %{$list} ]; my $random_thing; if ($user_input && $user_input =~ /(?:help|options)/) { $random_thing = 'Your options are: '.join(', ',sort @{$$list{'keys +'}}).', or all.'; } elsif ($user_input && $user_input =~ /dump/) { use Data::Dumper; $random_thing = Dumper($list); } else { my $input = $user_input ? $user_input : 'all'; my @random_list = shuffle(@{$$list{$input}}); $random_thing = $random_list[rand @random_list]; } $list->{'all'} = []; $list->{'keys'} = []; return $random_thing; }
      No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
      Lady Aleena

        That's one way to do it. Or you could just delete the keys you don't want (re)included before you (re)populate them:

        sub random { my ($user_input, $list) = @_; delete $list->{all}; delete $list->{keys}; $list->{'all'} = [ map { @$_ } values %{$list} ]; $list->{'keys'} = [ grep {$_ !~ /(?:all|keys)/} keys %{$list} ];

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Why not leave %list as is ?
        sub random { my ($user_input, $list) = @_; if ($user_input =~ /(?:help|options)/) { my $keys = join ", ",keys %$list; return "Your options are: $keys, or all."; } elsif ($user_input eq 'dump') { use Data::Dumper; return Dumper($list); } else { my @values=(); if ($user_input eq 'all'){ @values = map { @$_ } values %$list; } else { @values = values @$list{$user_input}; } return (shuffle @values)[0]; } }
        poj

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1107825]
Approved by philipbailey
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2019-04-20 02:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I am most likely to install a new module from CPAN if:
















    Results (108 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!