I tried to find info on //= and found only a clumping of similar nomenclature vaguely saying it transfers info into arrays.

//= combines the // (defined-or) operator and the = (assignment) operatior into one, exactly like ||= (or + assign), += (add + assign), -= (subtract + assign), and many others.

The // (defined-or) operator is relatively new, it was introduced in 5.10.0 and you can find a short intro in perl5100delta:

Defined-or operator

A new operator // (defined-or) has been implemented. The following expression:

$a // $b

is merely equivalent to

defined $a ? $a : $b

and the statement

$c //= $d;

can now be used instead of

$c = $d unless defined $c;

The // operator has the same precedence and associativity as ||. Special care has been taken to ensure that this operator Do What You Mean while not breaking old code, but some edge cases involving the empty regular expression may now parse differently. See perlop for details.


my $ref = \%database; $ref = $ref->{$_} //= {} for @$fields;

is puzzling.

Yes, it is. Partly because it is optimized for minimal keystrokes, not for readability. A typical beginner's mistake.

But it does not take much to decode. You should now know //=. $ref is initially a reference to the hash %database. (If you know C, a reference can be thought of as a pointer.) $ref->{$_} //= {} assigns a new, empty hash ({}) to $ref->{$_} unless $ref->{$_} exists and is not undef. Then, $ref is assigned whatever is stored in $ref->{$_}. And finally, the entire $ref = $ref->{$_} //= {} is executed for all elements of the $fields array reference, setting $_ to each array element. (Technically, $_ is aliased, but it does not matter here.)

The same code, but much more verbose, looks like this:

my $ref = \%database; foreach my $field (@$fields) { unless (defined $ref->{$field}) { $ref->{$field} = {}; } $ref = $ref->{$field}; }

(Seven lines instead of just two. What a waste of disk space and screen estate! And all the wear on the keyboard for those unnecessary characters! A single line would have been sufficient, no whitespace needed at all: my$r=\%d;$r=$r->{$_}//={}for@$f; - SCNR)

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^5: Building a dynamic array or some other method? by afoken
in thread Building a dynamic array or some other method? by CAdood

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.