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

Dear monks

I am a perl beginner and i am having trouble understanding the following code snippet

my ($name, $source); $sth->bind_columns(\$name, \$source); my %by_source; push @{$by_source{$source}}, $name while $sth->fetch; $sth->finish; if(scalar keys %by_source) { foreach my $s(sort {$a <=> $b} keys %by_source) { return shift @{$by_source{$s}}; } }
I understand that 2 variables are bound to 2 columns returned from a database query. I believesth->fetch is returning an array for each database row and the first column is assigned to $name and the second column is assigned to $source.But then it looks as though the hash element  $by_source{$source} contains an array ref which is being dereferenced and the value of $name is being pushed onto that array. But that makes no sense as the hash is empty?? Perhaps once i understand this bit I will be able to work out the other lines myself (but an explanation of those lines would be appreciated).

thank you kindly

Replies are listed 'Best First'.
Re: help understanding code snippet
by Anonymous Monk on Apr 28, 2011 at 00:16 UTC
    But that makes no sense as the hash is empty??

    Its called autovivification, it means if you use it like an array ref it magically becomes an arrayref

    use Data::Dump::Streamer; my %Hash; Dump(\%Hash); $Hash{'Empty'}[0] = 'no longer'; Dump(\%Hash); __END__ $HASH1 = {}; $HASH1 = { Empty => [ 'no longer' ] };
    See autovivification, autovivification
Re: help understanding code snippet
by anonymized user 468275 (Curate) on Apr 28, 2011 at 14:18 UTC
    Although I don't like to rely on autovivication because it doesn't work for every case. I don't like to follow the boundary of arbitrary rules (unless avoiding tax ;);)) So in my code, for example, you'll find initialisations ahead of the array reference usage like:
    $bysource{$source} ||= []; push etc.

    One world, one people

      I don't like to rely on autovivication because it doesn't work for every case

      I can't remember to have ever had problems with things not having been autovivified when they should've been. Could you come up with an example where it would fail?

      The problems with autovivification are usually the other way around, i.e. that people don't expect or don't want autovivified items as a side effect...   Luckily, there's now no autovivification for cases like these.