Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typeglob aliases

Tags:

perl

Okay, so it's easy to create a reference to an array...

my @a;
my $b=\@a;
#can now reference the same list of scalars from either @$b or @a

But how can I do this in reverse? For instance:

my $a=[1..4];
my @b;
#some magic happens here and now @b is an alias for @$a
@b=(6..10);
print "@$a\n";  #should print "6 7 8 9 10"

I assume this would happen through typeglobs, but those just elude me. Ideas?

Also it would be nice to do the same for hashes as well as arrays.

EDIT: This seems to work, but it's a tad kludgy as it just copies the anon array elements to the "alias" and then re-points itself to the array:

my @b=@$a;
$a=\@b;

Any better ideas?

like image 730
mswanberg Avatar asked Dec 04 '22 00:12

mswanberg


2 Answers

Three ways:

  1. Refaliasing.

    5.22 added an experimental feature that does exactly what you want.

    use experimental qw( refaliasing );
    \my @B = $A;
    

    5.26 added a second experimental feature that allows the following:

    use experimental qw( refaliasing declared_refs );
    my \@B = $A;
    

    Note that, being an experimental features, these features are subject to change and removal at any time.

  2. Glob aliasing

    Perl calls "type glob", or "glob" for short, its symbol table entry data structure. It is possible to set the entries in this data structure to a reference to name that reference.

    local our @B;
    *B = $A;      # Sets the array slot of "B", @B.
    

    Note that we have to use a package variables, so the variable is globally visible.

  3. Data::Alias

    alias my @B = @$A;
    
like image 95
ikegami Avatar answered Dec 25 '22 02:12

ikegami


All variables in a perl programs are stored in namespaces. There are two types of namespaces:

  1. Symbol tables. It is a global hash which stores record of global variables.
  2. Lexical scopes. It is anonymous temporary memory which is stored, not a PARTICULAR symbol table but it is attached to a block of your program. They store variables which we can see only in that program block.

Typeglobs are used to define a record (a variable, an array etc.) of Symbol tables, but not Lexical scopes. So, when you use this part of code:

my @b;
*b = $a;

you will get it:

Name "main::b" used only once:

This says us that the record main::b is not defined in a Symbol tables by us, but we can do it with a modifier "our". Therefore when you write so:

our @b;
*b = $a;

We can get an usefull result for us because *b is stored in a Symbol tables and we can use an operator * typeglob.

like image 37
edem Avatar answered Dec 25 '22 02:12

edem