Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I name an anonymous array in Perl?

Tags:

arrays

perl

#!/usr/bin/perl -w

use strict;

my $aref = [1, 2, 3];
my @a = @$aref;              # this line
$a[1] = 99;
print "aref = @$aref\n";
print "a = @a\n";

produces output:

aref = 1 2 3
a = 1 99 3

The output shows that @a and @$aref do not refer to the same array.

The marked line is where my problem lies. The value of scalar $aref is a reference to an anonymous array. In the marked line I was hoping to be able to make the array variable @a refer to that array, but what happens is that the anonymous array is copied and @a refers to a copy of the anonymous array. The assignment and print statements show this.

I understand that when you assign to an array the right hand side of the assignment is a list context, so the @$aref is coerced to a list of its elements. Is there a way to give the name @a to the array referred to by $aref?

like image 361
Norman of Anstruther Avatar asked Jul 29 '15 16:07

Norman of Anstruther


People also ask

How do I create an anonymous array in Perl?

You create an anonymous array by using square brackets like this: $arrayref = [ 'one', 'two', 'three' ]; There exists an array that has no name but is available via the $arrayref reference, which is just like any other array reference in all other respects.

How an anonymous array is used in Perl?

Perl anonymous references These types of references are called anonymous references. The rules of creating anonymous references are as follows: To get an array reference, use square brackets [] instead of parentheses. To get a hash reference, use curly brackets {} instead of parentheses.

What is anonymous hash in Perl?

An anonymous hash is simply a hash without a name. Both named and anonymous hashes have references, and \%hash is no more a direct reference than { foo => "bar" } . You imply that the latter is an indirect reference. – Borodin.

What is the difference between Perl list and Perl array?

A list is an ordered collection of scalars. An array is a variable that contains a list. In Perl, the two terms are often used as if they're interchangeable. But, to be accurate, the list is the data, and the array is the variable.


2 Answers

I wonder why would you want to do this? I presume it's a performance issue, but the usual solution is to pass your data around by reference. It is just as easy to write $aref->[1] as $a[1]

You could alias your reference in the package symbol table by assigning to the typeglob, but the alias must be a package variable

use strict;
use warnings;

my $aref = [1, 2, 3];

our @a;
*a = $aref;

$a[1] = 99;

print "aref = @$aref\n";
print "a    = @a\n";

output

aref = 1 99 3
a    = 1 99 3

There are a number of modules that offer a nice syntax and allow you to alias lexical variables

Here's a version that uses Lexical::Alias which has the advantage of aliasing lexical variables, and could be more robust than assigning to typeglobs. Data::Alias works in a very similar way. The output is identical to the above

use strict;
use warnings;

use Lexical::Alias qw/ alias_r /;

my $aref = [1, 2, 3];

alias_r $aref, \my @a;

$a[1] = 99;

print "aref = @$aref\n";
print "a    = @a\n";

an alternative way is to use alias instead of alias_r with

alias @$aref, my @a;
like image 133
Borodin Avatar answered Sep 30 '22 18:09

Borodin


  1. our @array; local *array = $aref;
    

    Pros: Built-in feature since 5.6.
    Cons: Ugly. Uses a global variable, so the variable is seen by called subs.

  2. use Data::Alias qw( alias );
    alias my @array = @$aref;
    

    Pros: Clean.
    Cons: This module gets broken by just about every Perl release (though it gets fixed quickly if not before the actual release).

  3. use feature qw( refaliasing );
    no warnings qw( experimental::refaliasing );
    \my @array = $aref;
    

    Pros: Built-in feature.
    Cons: Requires Perl 5.22+, and even then, the feature is experimental.

like image 23
ikegami Avatar answered Sep 30 '22 19:09

ikegami