http://qs321.pair.com?node_id=11137628

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

this POD is either confusing or plain wrong

https://perldoc.perl.org/perlref#Declaring-a-Reference-to-a-Variable

In reality is the warning disabled with no warnings 'experimental::declared_refs';

the experimental::refaliasing warning belongs to https://perldoc.perl.org/perlref#Assigning-to-References

Sample code:

use strict; use warnings; use Data::Dump qw/pp dd/; use feature qw( declared_refs refaliasing say ); no warnings 'experimental::refaliasing'; my $a = [666]; my @a; \@a = $a; say $a[0]; no warnings 'experimental::declared_refs'; my \@arr = [42];

C:/Strawberry/perl/bin\perl.exe -w d:/tmp/pm/auto_ref.pl 666 Compilation finished at Sat Oct 16 14:45:33

NB: that use feature qw(declared_refs) doesn't seem to make sense without the other feature.

my \@arr; without assignment will create a new warning "Useless use of single ref constructor in void context"

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: POD for use feature 'declared_refs' wrong
by kcott (Archbishop) on Oct 17, 2021 at 07:28 UTC

    G'day Rolf,

    "this POD is either confusing or plain wrong"

    I'd say a bit of both.

    In the context of the first paragraph of "Declaring a Reference to a Variable", experimental::refaliasing should definitely be replaced with experimental::declared_refs.

    That section goes on to say, "It is intended mainly for use in assignments to references ...". It would be appropriate to mention experimental::refaliasing at this point.

    "NB: that use feature qw(declared_refs) doesn't seem to make sense without the other feature."

    There are instances where you want a declaration without assignment (not in "void" context).

    I've certainly used "\my VAR" in this context often enough. This doesn't require any special feature or warnings code.

    $ perl -E ' use strict; use warnings; say ref \my $scalar; say ref \my @array; ' SCALAR ARRAY

    Off the top of my head, I couldn't think of an application for "my \VAR" in this context; however, just for completeness, here's a contrived example showing that "declared_refs" is required but "refaliasing" is not.

    $ perl -E ' use strict; use warnings; say ref my \$scalar; say ref my \@array; ' The experimental declared_refs feature is not enabled at -e line 4. $ perl -E ' use strict; use warnings; use feature "declared_refs"; say ref my \$scalar; say ref my \@array; ' Declaring references is experimental at -e line 5. Declaring references is experimental at -e line 6. SCALAR ARRAY $ perl -E ' use strict; use warnings; use feature "declared_refs"; no warnings "experimental::declared_refs"; say ref my \$scalar; say ref my \@array; ' SCALAR ARRAY

    While these features remain experimental, they're rather unwieldy [see Update below] and probably easy to get wrong:

    $ perl -E ' use strict; use warnings; use feature qw{refaliasing declared_refs}; no warnings qw{experimental::refaliasing experimental::declared_re +fs}; my ($sc, @ar) = qw{qwert asdfg zxcvb}; my \$scalar = \$sc; my \@array = \@ar; say $scalar; say "@array"; ' qwert asdfg zxcvb

    [Note: Perl 5.34 used for all examples.]

    Update: Regarding my comment about experimental features being unwieldy; they are, in fact, not as unwieldy as I presented. I had forgotten about the experimental pragma (thanks to ++ikegami for the reminder). The two lines:

    use feature qw{refaliasing declared_refs}; no warnings qw{experimental::refaliasing experimental::declared_re +fs};

    can be reduced to the much simpler one line:

    use experimental qw{refaliasing declared_refs};

    — Ken

      WRT your last point, these features are useful when one wants to avoid repeated dereferences of list items inside loops. Doing so can give a small speed gain but my experience is that they need to avoid a pretty high number of derefs to make a meaningful difference. The same applies to Data::Alias for earlier perl versions.

      A highly contrived (and incomplete) example is below. The main point is that it avoids dereferencing calls such as $path->[$i].

      \my @path = $some_array_ref; my $accumulator; for my $i (0..@$path) { $accumulator += $path[$i]; }
      Thanks Ken,

      you are right, it's possible to use my $var; in non-void context, actually I'm regularly prepending warn for debugging.°

      > While these features remain experimental, they're rather unwieldy and probably easy to get wrong:

      They are indeed not nice to activate, I'd probably write a module bundling those four steps to avoid boilerplate.

      But the feature is very nice in many circumstances, Brian d Foy² lists some here:

      it's also very handy when working with aliases, and one doesn't want to litter ones code with cryptic $_[N°]

      D:\tmp\pm>perl -Mfeature=:all -M-warnings sub uc_name { my \$name = \$_[0]; $name = uc $name } $n="ken"; uc_name($n); say $n __END__ KEN

      FWIW Perl4 had an aliasing feature with *type-globs, but this was restricted to package vars.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      °) actually I'm even putting the warn into the line before, like this I'm flexible with (un)commenting it.

      # warn my $x = ...;

      ²) corrected spelling twice (= deux fois ;)

        "FWIW Perl4 had an aliasing feature ..."

        Purely as an historical note, I do recall reading about that in the first Camel book. In perlhist:

        Perl 4 introduced the first Camel book.  Really.  We mostly just
            switched version numbers so the book could refer to 4.000.
        

        So that feature would have existed in Perl3. I don't have any information on which specific Perl version introduced it. I don't believe I used that feature in any version prior to Perl5.

        — Ken

        They are indeed not nice to activate, I'd probably write a module bundling those four steps to avoid boilerplate.

        Which four steps? Enabling the two features and disabling the two warnings? It already exists.

        use experimental qw( refaliasing declared_refs );
      [deleted]
Re: POD for use feature 'declared_refs' wrong
by ikegami (Patriarch) on Oct 18, 2021 at 13:47 UTC

    use feature qw(declared_refs) doesn't seem to make sense without the other feature.

    Yes, but the refaliasing does make sense without declared_refs, so it's possible that refaliasing could be accepted without declared_refs.

    Upd: Removed incorrect claim once present here. Bad test.


    Use of refalising and declared_refs:
    $ perl -M5.022 -e' my $x = 123; \my $y = \$x; say $y; ' Experimental aliasing via reference not enabled at -e line 2. $ perl -M5.022 -e' use feature qw( refaliasing ); my $x = 123; \my $y = \$x; say $y; ' Aliasing via reference is experimental at -e line 3. 123 $ perl -M5.022 -e' use feature qw( refaliasing ); no warnings qw( experimental::refaliasing ); my $x = 123; \my $y = \$x; say $y; ' 123 $ perl -M5.022 -e' use experimental qw( refaliasing ); my $x = 123; \my $y = \$x; say $y; ' 123
    $ perl -M5.026 -e' my $x = 123; my \$y = \$x; say $y; ' The experimental declared_refs feature is not enabled at -e line 2. $ perl -M5.026 -e' use feature qw( declared_refs ); my $x = 123; my \$y = \$x; say $y; ' Declaring references is experimental at -e line 3. Experimental aliasing via reference not enabled at -e line 3. $ perl -M5.026 -e' use feature qw( refaliasing declared_refs ); my $x = 123; my \$y = \$x; say $y; ' Declaring references is experimental at -e line 3. Aliasing via reference is experimental at -e line 3. 123 $ perl -M5.026 -e' use feature qw( refaliasing declared_refs ); no warnings qw( experimental::refaliasing experimental::declared_re +fs ); my $x = 123; my \$y = \$x; say $y; ' 123 $ perl -M5.026 -e' use experimental qw( refaliasing declared_refs ); my $x = 123; my \$y = \$x; say $y; ' 123

    Upd: Dropped requirement to 5.22 for refaliasing part.