как создать псевдонимы perl?тип-глоба? - PullRequest
0 голосов
/ 25 июня 2018

Предположим, я манипулирую хешем, который находится в другом пакете, и хочу создать псевдоним этой переменной?Какой чистый способ сделать это?Этот пример кода показывает, что я хочу сделать, но это, и дюжина вариантов его неисправности.

#!/usr/bin/perl
#use strict;  # I want it to work with strict.

my $p = Person->new("Joe");
my $name;
*name = \*$p->{"name"};     # Latest broken attempt

printf("'%s' should eq '%s' because they both point to the same place.\n",
       $name, $p->{"name"});

$name = "Sam";

printf("'%s' should eq '%s' because they both point to the same place.\n",
       $name, $p->{"name"});
exit 0;


package Person;

sub new {
    my $class = shift;

    my $this = {};
    bless $this, $class;

    $this->{"name"} = shift;

    return $this;
}

Функциональность, которую я хочу, - это возможность манипулировать $p->{"name"} десятки раз без необходимости печатать$p->{"name"} повторно.Реальная структура данных намного сложнее с большим количеством вложенных хэшей.

Возможно, это что-то простое.Спасибо.

1 Ответ

0 голосов
/ 25 июня 2018

Самый простой способ - сделать копию:

use strict;
use warnings;
my $p = { name => "Joe" };
my $name = $p->{name};
print "'$name' is '$p->{name}'\n";

Это то, что я бы использовал, если мне не нужно присваивать $name.

Если вы хотитечтобы иметь возможность писать через $name, самый простой способ - сделать это ссылкой:

use strict;
use warnings;
my $p = { name => "Joe" };
my $name = \$p->{name};
print "'$$name' is '$p->{name}'\n";
$$name = "Jill";
print "'$$name' is '$p->{name}'\n";

Если вы действительно хотите использовать псевдоним, самый простой способ - использовать цикл for:

use strict;
use warnings;
my $p = { name => "Joe" };
for my $name ($p->{name}) {
    print "'$name' is '$p->{name}'\n";
    $name = "Jill";
    print "'$name' is '$p->{name}'\n";
}

Если ваш perl достаточно новый (5.22+), вы также можете использовать псевдонимы по ссылкам:

use strict;
use warnings;
use feature 'refaliasing';
my $p = { name => "Joe" };
\my $name = \$p->{name};
print "'$name' is '$p->{name}'\n";
$name = "Jill";
print "'$name' is '$p->{name}'\n";

Наконец, вы можете делать псевдонимы для переменных пакета, назначая typeglobs, ноэто не то, что я бы на самом деле использовал здесь:

use strict;
use warnings;
my $p = { name => "Joe" };
*name = \$p->{name};  # sets *name{SCALAR} to point to $p->{name}
our $name;            # declares $name so we can use it to refer to $main::name
print "'$name' is '$p->{name}'\n";
$name = "Jill";
print "'$name' is '$p->{name}'\n";
...