Data::Alias 1.11 - Comprehensive set of aliasing operations


System requirements:

  All platforms:  requires perl 5.8.1 or later
  Win32:          requires perl 5.8.9 or later (or just use Cygwin)
  AIX:            requires perl 5.8.9 or later


To install this module type the following:

  perl Makefile.PL
  make
  make test
  make install


Module documentation:

NAME
   Data::Alias - Comprehensive set of aliasing operations

SYNOPSIS
       use Data::Alias;

       alias {
               # aliasing instead of copying whenever possible
       };

       alias $x = $y;              # alias $x to $y
       alias @x = @y;              # alias @x to @y
       alias $x[0] = $y;           # similar for array and hash elements
       alias push @x, $y;          # push alias to $y onto @x
       $x = alias [ $y, $z ];      # construct array of aliases
       alias my ($x, $y) = @_;     # named aliases to arguments
       alias { ($x, $y) = ($y, $x) };              # swap $x and $y
       alias { my @t = @x; @x = @y; @y = @t };     # swap @x and @y

       use Data::Alias qw/ alias copy /;

       alias { copy $x = $y };     # force copying inside alias-BLOCK

       use Data::Alias qw/ deref /;

       my @refs = (\$x, \@y, \%z);
       foo(deref @refs)            # same as foo($x, @y, %z)

DESCRIPTION
   Aliasing is the phenomenon where two different expressions actually
   refer to the same thing. Modifying one will modify the other, and if you
   take a reference to both, the two values are the same.

   Aliasing occurs in Perl for example in for-loops and sub-calls:

       for $var ($x) {
               # here $var is an alias to $x
       }

       foo($y);
       sub foo {
               # here $_[0] is an alias to $y
       }

   Data::Alias is a module that allows you to apply "aliasing semantics" to
   a section of code, causing aliases to be made whereever Perl would
   normally make copies instead. You can use this to improve efficiency and
   readability, when compared to using references.

   The exact details of aliasing semantics are below under "DETAILS".

SYNTAX
 alias EXPR | alias BLOCK
   Exported by default.

   Enables aliasing semantics within the expression or block. Returns an
   alias to the expression, or the block's return value.

   "alias" is context-transparent, meaning that whichever context it is
   placed in (list, scalar, void), the expression/block is evaluated in the
   same context.

 copy EXPR | copy BLOCK
   Restores normal (copying) semantics within the expression or block, and
   makes a copy of the result value (unless in void context).

   Like "alias", "copy" is context-transparent.

 deref LIST
   Accepts a list of references to scalars, arrays, or hashes. Applies the
   applicable dereferencing operator to each. This means that:

       deref $scalarref, $arrayref, $hashref

   behaves like:

       $$scalarref, @$arrayref, %$hashref

EXAMPLES
   A common usage of aliasing is to make an abbreviation for an expression,
   to avoid having to repeat that (possibly verbose or ugly) expression
   over and over:

       alias my $fi = $self->{FrobnitzIndex};
       $fi = $fi > 0 ? $fi - $adj : $fi + $adj;

       sub rc4 {
               alias my ($i, $j, $S) = @_;
               my $a = $S->[($i += 1) &= 255];
               my $b = $S->[($j += $S->[$i]) &= 255];
               $S->[(($S->[$j] = $a) + ($S->[$i] = $b)) & 255]
       }

   In the second example, the rc4 function updates its first two arguments
   (two state values) in addition to returning a value.

   Aliasing can also be used to avoid copying big strings. This example
   would work fine without "alias" but would be much slower when passed a
   big string:

       sub middlesection ($) {
               alias my $s = shift;
               substr $s, length($s)/4, length($s)/2
       }

   You can also apply aliasing semantics to an entire block. Here this is
   used to swap two arrays in O(1) time:

       alias {
               my @temp = @x;
               @x = @y;
               @y = @temp;
       };

   The "copy" function is typically used to temporarily reinstate normal
   semantics, but can also be used to explicitly copy a value when perl
   would normally not do so:

       my $ref = \copy $x;

DETAILS
   This section describes exactly what the aliasing semantics are of
   operations. Anything not listed below has unaltered behaviour.

   scalar assignment to variable or element.
       Makes the left-side of the assignment an alias to the right-side
       expression, which can be anything.

           alias my $lexvar = $foo;
           alias $pkgvar = $foo;
           alias $array[$i] = $foo;
           alias $hash{$k} = $foo;

       An attempt to do alias-assignment to an element of a tied (or
       "magical") array or hash will result in a "Can't put alias into tied
       array/hash" error.

   scalar assignment to dereference
       If $ref is a reference or undef, this simply does "$ref = \$foo".
       Otherwise, the indicated package variable (via glob or symbolic
       reference) is made an alias to the right-side expression.

           alias $$ref = $foo;

   scalar assignment to glob
       Works mostly the same as normal glob-assignment, however it does not
       set the import-flag. (If you don't know what this means, you
       probably don't care)

           alias *glob = $reference;

   scalar assignment to anything else
       Not supported.

           alias substr(...) = $foo;   # ERROR!
           alias lvalsub() = $foo;     # ERROR!

   conditional scalar assignment
       Here $var (and $var2) are aliased to $foo if the applicable
       condition is satisfied. $bool and $foo can be any expression. $var
       and $var2 can be anything that is valid on the left-side of an
       alias-assignment.

           alias $bool ? $var : $var2 = $foo;
           alias $var &&= $foo;
           alias $var ||= $foo;
           alias $var //= $foo; # (perl 5.9.x or later)

   whole aggregate assignment
       These alias entire aggregates (arrays or hashes), not merely their
       contents. This means for example that "\@lexarray == \@foo".

           alias my @lexarray = @foo;
           alias my %lexhash = %foo;
           alias @pkgarray = @foo;
           alias %pkghash = %foo;

       Making the left-side a dereference is also supported:

           alias @$ref = @foo;
           alias %$ref = %foo;

       and analogously to assignment to scalar dereference, these will
       change $ref to reference the aggregate, if $ref was undef or already
       a reference. If $ref is a string or glob, the corresponding package
       variable is aliased.

       If the right-side expression is not an aggregate (of the same type),
       then a new one is implicitly constructed. This means:

           alias my @array = ($x, $y, $z);
           alias my %hash = (x => $x, y => $y);

       is translated to:

           alias my @array = @{ [$x, $y, $z] };
           alias my %hash = %{ {x => $x, y => $y} };

       If you want to merely replace the contents of the aggregate with
       aliases to the contents of another aggregate, but not alias the
       aggregates themselves, you can force list-assignment by
       parenthesizing the left side, see below.

   list assignment
       List assignment is any assignment where the left-side is an
       array-slice, hash-slice, or list in parentheses. This behaves
       essentially like many scalar assignments in parallel.

           alias my (@array) = ($x, $y, $z);
           alias my (%hash) = (x => $x, y => $y);
           alias my ($x, $y, @rest) = @_;
           alias @x[0, 1] = @x[1, 0];

       Any scalars that appear on the left side must be valid targets for
       scalar assignment. When an array or hash appears on the left side,
       normally as the last item, its contents are replaced by the list of
       all remaining right-side elements. "undef" can also appear on the
       left side to skip one corresponding item in the right-side list.

       Beware when putting a parenthesized list on the left side. Just like
       Perl parses "print (1+2)*10" as "(print(1+2))*10", it would parse
       "alias ($x, $y) = ($y, $x)" as "(alias($x, $y)) = ($y, $x)" which
       does not do any aliasing, and results in the "Useless use of alias"
       warning, if warnings are enabled.

       To circumvent this issue, you can either one of the following:

           alias +($x, $y) = ($y, $x);
           alias { ($x, $y) = ($y, $x) };

   Anonymous aggregate constructors
       Return a reference to a new anonymous array or hash, populated with
       aliases. This means that for example "\$hashref->{x} == \$x".

           my $arrayref = alias [$x, $y, $z];
           my $hashref = alias {x => $x, y => $y};

       Note that this also works:

           alias my $arrayref = [$x, $y, $z];
           alias my $hashref = {x => $x, y => $y};

       but this makes the lhs an alias to the temporary, and therefore
       read-only, reference made by "[]" or "{}". Therefore later attempts
       to assign to $arrayref or $hashref results in an error. The
       anonymous aggregate that is referenced behaves the same in both
       cases obviously.

   Array insertions
       These work as usual, except the inserted elements are aliases.

           alias push @array, $foo;
           alias unshift @array, $foo;
           alias splice @array, 1, 2, $foo;

       An attempt to do any of these on tied (or "magical") array will
       result in a "Can't push/unshift/splice alias onto tied array" error.

   Returning an alias
       Returns aliases from the current "sub" or "eval". Normally this only
       happens for lvalue subs, but "alias return" can be used in any sub.

   Subroutines and evaluations
       Placing a subroutine or "eval STRING" inside "alias" causes it to be
       compiled with aliasing semantics entirely. Additionally, the return
       from such a sub or eval, whether explicit using "return" or
       implicitly the last statement, will be an alias rather than a copy.

           alias { sub foo { $x } };

           my $subref = alias sub { $x };

           my $xref1 = \foo;
           my $xref2 = \alias eval '$x';
           my $xref3 = \$subref->();

       Explicitly returning an alias can also be done using "alias return"
       inside any subroutine or evaluation.

           sub foo { alias return $x; }
           my $xref = \foo;

   Localization
       Use of local inside "alias" usually behaves the same as local does
       in general, however there is a difference if the variable is tied:
       in this case, Perl doesn't localize the variable at all but instead
       preserves the tie by saving a copy of the current value, and
       restoring this value at end of scope.

           alias local $_ = $string;

       The aliasing semantics of "local" avoids copying by always
       localizing the variable itself, regardless of whether it is tied.

IMPLEMENTATION
   This module does not use a source filter, and is therefore safe to use
   within eval STRING. Instead, Data::Alias hooks into the Perl parser, and
   replaces operations within the scope of "alias" by aliasing variants.

   For those familiar with perl's internals: it triggers on a ck_rv2cv
   which resolves to the imported "alias" sub, and does a parser hack to
   allow the "alias BLOCK" syntax. When the ck_entersub is triggered that
   corresponds to it, the op is marked to be found later. The actual work
   is done in a peep-hook which is installed on the ck_rv2cv trigger, and
   processes the marked entersub and its children, replacing the pp_addrs
   with aliasing replacements. The peep hook will also take care of any
   subs defined within the lexical (but not dynamical) scope between the
   ck_rv2cv and the ck_entersub. When no marked entersubs remain, the
   Data::Alias-peeper stops and is deinstalled.

KNOWN ISSUES
   Lexical variables
       When aliasing existing lexical variables, the effect is limited in
       scope to the current subroutine and any closures create after the
       aliasing is done, even if the variable itself has wider scope. While
       partial fixes are possible, it cannot be fixed in any reliable or
       consistent way, and therefore I'm keeping the current behaviour.

ACKNOWLEDGEMENTS
   Specials thanks go to Elizabeth Mattijsen, Juerd Waalboer, and other
   members of the Amsterdam Perl Mongers, for their valuable feedback.

AUTHOR
   Matthijs van Duin <[email protected]> developed the module originally,
   and maintained it until 2007. Andrew Main (Zefram) <[email protected]>
   updated it to work with Perl versions 5.11.0 and later.

LICENSE
   Copyright (C) 2003-2007 Matthijs van Duin. Copyright (C) 2010,
   2011 Andrew Main (Zefram) <[email protected]>. All rights reserved.
   This program is free software; you can redistribute it and/or modify
   it under the same terms as Perl itself.