Приглашаем посетить
Огарев (ogarev.lit-info.ru)

Section 11.2.  Braced References

Previous
Table of Contents
Next

11.2. Braced References

Where prefix dereferencing is unavoidable, put braces around the reference.

You can dereference a reference without first putting it in braces:

    push @$list_ref, @results;

    print substr($$str_ref, 0, $max_cols);

    my $first = $$list_ref[0];
    my @rest  = @$list_ref[1..$MAX];
    my $first_name = $$name_ref{$first};
    my ($initial, $last_name) = @$name_ref{$middle, $last};

    print @$$ref_to_list_ref[1..$MAX];

All of these work correctly, but they may also produce intense uncertainty and anxiety on the part of future readers of your code, who will fret about the relative precedences of the multiple sigils, and of the indexing brackets and braces. Or they will misread the leading $$... sequence as being related to the $$ (a.k.a. $PID) variableespecially in string interpolations:

    print "Your current ID is: JAPH_$$_ID_REF\n";

Braced references are always visually unambiguous:


    print "Your current ID is: JAPH_${$_ID_REF}\n";

And they give the reader better clues as to the internal structure of dereference:


    push @{$list_ref}, @results;

    print substr(${$str_ref}, 0, $max_cols);

    my $first = ${$list_ref}[0];
    my @rest  = @{$list_ref}[1..$MAX];

    my $first_name = ${$name_ref}{$first};
    my ($initial, $last_name) = @{$name_ref}{$middle, $last};

    print @{${$ref_to_list_ref}}[1..$MAX];

In some cases, bracketing can prevent subtle errors caused by the ambiguity of human expectations:

    my $result = $$$stack_ref[0];

By which the programmer may have intended:

    my $result = ${${$stack_ref[0]}};

or:

    my $result = ${${$stack_ref}[0]};

or:

    my $result = ${${$stack_ref}}[0];

If you're not entirely sure which of those three alternatives the unbracketed $$$stack_ref[0] is actually equivalent to[*], that illustrates precisely how important it is to use the explicit braces. Or, better still, to unpack the reference in stages:

[*] $$$stack_ref[0] is the same as ${${$stack_ref}}[0]. Indexing brackets are of lower precedence than sigils.


    my $direct_stack_ref = ${$stack_ref};
    my $result = $direct_stack_ref->[0];

    Previous
    Table of Contents
    Next