in reply to Initializing Hash Arrays in Perl

This is what that structure (minimally) looks like:

%REFERRERS = ( $campaign_id => { $skin_id => { $refr_url => __some_value__ }, }, );

...where $campaign_id, $skin_id, and $refr_url are scalar variables that hold the names of hash keys. There really is no $REFERRERS variable (a scalar), there is a %REFERRERS, which is a hash.

Perl has autovivification, so let's say that there doesn't yet exist a hash key named "foo". Then saying $REFERRERS{foo} = 1 causes that hash element to become available, and the value that hash element holds is 1. Let's say that your hash is entirely empty: %REFERRERS = () ...empty. By incrementing $REFERRERS{foo}{bar}{baz}++, an element inside of %REFERRERS is created, named 'foo'. Its value is set to a reference to an anonymous hash with a key named "bar", which is set to a reference to an anonymous hash with a key named "baz", and finally that element is incremented from its undefined state to "1".


Dave

Replies are listed 'Best First'.
Re^2: Initializing Hash Arrays in Perl
by winterwind (Initiate) on Feb 14, 2014 at 01:50 UTC
    Kenosis and Davido, you both hit the nail on the head. The purpose of it is precisely what Kenosis said as well. I understand the hash creation now but the ++ seems very odd to me. How can the $refr_url be initialized as ++? It has not been defined as anything yet. Is it something like: undef++ which evaluates to 1? I don't understand how a key's value can be incremented when it hasn't even been defined as anything yet.

      You've pretty much got it. In Perl, all scalar containers (ie, a scalar variable, an element from an array, or an element from a hash) start out as "undef", which is different from C's notion of undefined. In C, undefined means "could be anything, but never anything useful". In Perl, undefined means "undef", the value. In numeric context, undef equates to zero, meaning if you treat undef as a number it acts like zero. Increment zero, and you get 1.

      You can explicitly detect definedness with defined:

      perl -E 'say "undefined" if ! defined($var);'

      ...or...

      perl -E '$var = 1; say "defined" if defined($var);'

      But numeric operations, including Boolean comparisons in numeric context cause undef to act like a "false" numeric value, which is to say, zero.

      perl -E 'say "Hello" if undef == 0;'

      ...or...

      my $var; # Currently $var is undef print $var + 5, "\n"; # 5 print ++$var, "\n"; # 1

      That's really the less amazing thing. The more amazing thing is that you can implicitly create references to anonymous data structures. Consider this:

      my %hash; $hash{foo} = { bar => 'baz' };

      The { ... } curly braces around  bar => 'baz' act as explicit anonymous hash constructors, so the resulting structure looks like this:

      %hash = ( foo => { # { is an anon-hash constructor bar => 'baz' } );

      That's the boring explicit way. But this will create the exact same structure, without explicitly constructing the inner hashref:

      my %hash; $hash{foo}{bar} = 'baz';

      The { bar => 'baz'} hash ref was constructed implicitly.


      Dave