Как уже упоминалось в других ответах, tie
применяется к контейнерам, а не к значениям, поэтому невозможно присвоить связанную переменную другой переменной и сохранить связанные свойства.
Поскольку присвоение завершено, вам нужно передать контейнер в подпрограмму GetThing
.Вы можете сделать это путем ссылки следующим образом:
use strict;
use warnings;
main();
sub GetThing{
tie ${$_[1]}, 'mything', $_[0];
}
sub main {
my %m;
GetThing('Fred' => \$m{pre});
print "1\n";
print $m{pre};
print "2\n";
print $m{pre};
print "3\n";
}
package mything;
require Tie::Scalar;
my @ISA = qw(Tie::StdScalar);
sub TIESCALAR {
my $class = shift;
bless {
name => shift || 'noname',
}, $class;
}
sub FETCH {
my $self = shift;
print "ACCESS ALERT!\n";
return " NAME: '$self->{name}'\n";
}
, который производит правильный вывод.
Однако, если вы хотите сохранить назначение, вам нужно будет использовать перегрузку, которая применяется кценности (на самом деле для объектов, но сами они являются ценностями).Без более подробной информации о предполагаемой цели сложно дать полный ответ, но он будет соответствовать вашим заявленным требованиям:
use strict;
use warnings;
main();
sub GetThing{
return mything->new( shift );
}
sub main {
my %m;
$m{pre} = GetThing('Fred');
print "1\n";
print $m{pre};
print "2\n";
print $m{pre};
print "3\n";
}
package mything;
sub new {
my $class = shift;
bless {
name => shift || 'noname',
}, $class;
}
use overload '""' => sub { # '""' means to overload stringification
my $self = shift;
print "ACCESS ALERT!\n";
return " NAME: '$self->{name}'\n";
};
Обе связи и перегрузки могут быть сложными, поэтому прочитайте всю документацию, если естьне ясно.