Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Initializing Hash Arrays in Perl

by sundialsvc4 (Abbot)
on Feb 14, 2014 at 02:06 UTC ( #1074925=note: print w/ replies, xml ) Need Help??


in reply to Initializing Hash Arrays in Perl

What you are seeing here is a language-feature that does not, if I dimly-recall correctly, does not exist in PHP:   auto-vivification.

(It’s pig-latin for “comes to life automagically ...”)

Basically, it works like this:   “if Perl finds that whatever-is-required does not exist, Perl will automatically and silently create it.”   Therefore, in the start-from-nothing case, Perl will do all of the following:

  1. If $REFERRERS is not yet defined, it will automagically become a hashref, because that is what the situation requires.   (And if it is defined, but is not a hashref, “you die.”)
  2. If an entry corresponding to $campaign_id does not yet exist, it will magically appear.   And, since in the present context it needs to be “a hashref,” it will become one.
  3. ... ditto $skin_id ... (ad infinitum)
  4. ... ditto $ref_url ... however, since the operator to be applied (“++ ...”) calls for an integer, an integer with the value zero will be supplied.
  5. The integer – whether existing or new – will now be incremented.

(Way cool, huh?!)

All of this “convenience” is automatically done by Perl, in the name of “DWIM = Do What I Mean.™”   It may be the case that you must write PHP-specific code to do this.   (Or not ...   It’s been a few months since I’ve thought about PHP, so please don’t quote me on anything.)


Comment on Re: Initializing Hash Arrays in Perl
Re^2: Initializing Hash Arrays in Perl
by tobyink (Abbot) on Feb 14, 2014 at 09:30 UTC

    PHP does have autovivification, but only on write operations.

    <?php $arr = array(); $arr[0]['a'][1]['b'] = 2; print_r($arr); $other = array(); if ($other[0]['a'][1]['b'] == 2) { die; } else { # Note that autovivification has not happened. print_r($other); }

    Versus:

    #!/usr/bin/env perl use strict; use Data::Dumper; my @arr; $arr[0]{'a'}[1]{'b'} = 2; print Dumper \@arr; my @other; if ($other[0]{'a'}[1]{'b'} == 2) { die; } else { # Note that autovivification has happened! print Dumper \@other; }

    For the purposes of autovivification, ++ is considered a write operation.

    The Perl module autovivification allows you to have approximately the PHP behaviour:

    no autovivification;
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re^2: Initializing Hash Arrays in Perl
by AnomalousMonk (Abbot) on Feb 14, 2014 at 14:56 UTC
    1. If $REFERRERS is not yet defined, it will automagically become a hashref ... [emphasis added]

    A small but, IMO, important point: In the case cited (and if strictures were not enabled; see strict), a hash named  %REFERRERS of the package global flavor would be autovivified, not a hash reference. A hash reference would be created if the  -> operator were used (see perlop).

    c:\@Work\Perl>perl -w -MData::Dump -le "$REFERRERS{foo}{bar}{baz}++; ;; dd \%REFERRERS; " { foo => { bar => { baz => 1 } } } c:\@Work\Perl>perl -w -MData::Dump -le "$REFERRERS->{foo}{bar}{baz}++; ;; dd $REFERRERS; " { foo => { bar => { baz => 1 } } }
      Wow, thanks all! It's really great here! StackOverflow can only aspire to be like this place. I understand the line fully now and see that it's all about the context in Perl.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2014-12-27 13:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls