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

is anyone coding this way: (from 'Advanced Perl Programming'
@array = (10,20); Double(*array); sub Double { local *copy = shift; foreach my $element (@copy) { $element *=2; } }

Replies are listed 'Best First'.
Re: use of typeglob aliases
by BrowserUk (Patriarch) on Sep 05, 2013 at 16:23 UTC

    Not quite like that, and not for such simple uses as these, but but I often use typeglob aliasing to avoid complex dereferencing within subroutines:

    #! perl -slw use strict; sub processBigArray { our @alias; local *alias = shift; $_ += 1 for @alias; return; } my @a = 1 .. 1e6; processBigArray( \@a ); print for @a[ 0 .. 9 ]; __END__ C:\test>junk38 2 3 4 5 6 7 8 9 10 11

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Chapter 3, p 44
Re: use of typeglob aliases
by Athanasius (Archbishop) on Sep 05, 2013 at 16:33 UTC

    Another point: the typeglob technique works only if @array is a global (package) variable:

    2:29 >perl -MData::Dump -wE "my @array = (10, 20); Double(*array); dd + @array; sub Double { local *copy = shift; for my $element (@copy) { +$element *= 2; } }" Name "main::array" used only once: possible typo at -e line 1. (10, 20) 2:29 >

    The following code, using a reference instead of a typeglob, performs the equivalent operation, but is more flexible, as @array may be either a global or a lexical:

    2:29 >perl -MData::Dump -wE "my @array = (10, 20); Double(\@array); d +d @array; sub Double { my $array_ref = shift; for my $element (@$arra +y_ref) { $element *= 2; } }" (20, 40) 2:30 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      ... the typeglob technique ...

      I know that Athanasius is aware of this, but note that while the approach used in the OP and referred to above of taking and passing a 'pure' typeglob reference has the drawback of only working with globals, the approach of BrowserUk here works with both global (i.e., package) and lexical variables.

Re: use of typeglob aliases
by davido (Cardinal) on Sep 05, 2013 at 16:21 UTC

    List::MoreUtils::pairwise localizes typeglobs to *a and *b from the caller's package, which (I think) is a similar idea. For general parameter passing it seems a little outdated. Which version of Advanced Perl Programming? I don't remember seeing it in the 2nd Edition, and can't find it as I re-skim through the book. If you could provide a little more context (chapter, etc.) from the book maybe we could look to see what thought process went into it.


    Dave

      copyright 1997

        That is the 1st Edition of the book. In 1997 people were using Perl 5.003 and 5.004. Much has changed since then.

        In 2005, when the 2nd edition was published, Perl 5.8.6 was its contemporary. Much has changed since then as well.

        I think the 2nd Edition's treatment on typeglobs is about the best anywhere. But I can't comment on the 1st Edition. Where did you find it?


        Dave

Re: use of typeglob aliases
by digital_carver (Sexton) on Sep 05, 2013 at 16:23 UTC
    If you're intent on modifying the argument, why not do it directly instead of using local globs?
    @array = (10,20); Double(@array); print "@array"; sub Double { foreach my $element (@_) { $element *=2; } }
    @_ is an alias for the arguments sent, and the foreach loop makes $element an alias for each element of @_ in turn, so this works out and is reasonably clearer.
Re: use of typeglob aliases
by kcott (Archbishop) on Sep 06, 2013 at 07:23 UTC

    G'day fionbarr,

    [Note: When making references to publications it's good practice to specify edition, chapter and page. In this case: Advanced Perl Programming, 1st Edition - Chapter 3: Typeglobs and Symbol Tables - Page 44]

    This is a cut-down version of code from a section that starts:

    Efficient parameter passing

    Aliases happen to be quite a bit faster than references, because they don't need to do any dereferencing. ...

    I found typeglob aliases to be ~40% faster than references. Here's an average Benchmark:

    $ perl -Mstrict -Mwarnings -E ' use Benchmark qw{cmpthese}; my @original_array = (10, 20); sub glob_double { local *copy = shift; for (@::copy) { $_ *= 2; } } sub ref_double { my $array_ref = shift; for (@$array_ref) { $_ *= 2; } } cmpthese(-1 => { glob => sub { @::array = @original_array; glob_double(*array) +}, ref => sub { my @array = @original_array; ref_double(\@array) + }, }); + ' Rate ref glob ref 546132/s -- -28% glob 763738/s 40% --

    Almost identical code, along with a discussion, can be found in "perlsub - Passing Symbol Table Entries (typeglobs)".

    -- Ken