Как использовать переменную в качестве имени модуля в Perl?
Я знаю, что можно использовать переменную в качестве имени переменной для переменных пакета в Perl. Я хотел бы использовать содержимое переменной в качестве имени модуля. Например:
package Foo;
our @names =("blah1", "blah2");
1;
И в другом файле я хочу иметь возможность установить содержимое скаляра на "foo", а затем получить доступ к массиву имен в Foo
через этот скаляр.
my $packageName = "Foo";
По существу, я хочу сделать что-то в соответствии с:
@{$packageName}::names; #This obviously doesn't work.
Я знаю, что могу использовать
my $names = eval '$'. $packageName . "::names"
Но только если Foo::names
является скаляром. Есть ли другой способ сделать это без инструкции eval
?
Ответы
Ответ 1
Чтобы получить переменные пакета в пакете $package
, вы можете использовать символические ссылки:
no strict 'refs';
my $package = 'Foo';
# grab @Foo::names
my @names = @{ $package . '::names' }
Лучшим способом, который позволяет избежать символических ссылок, является выдержка метода внутри Foo
, который вернет массив. Это работает, потому что оператор вызова метода (->
) может принимать строку в качестве invocant.
package Foo;
our @names = ( ... );
sub get_names {
return @names;
}
package main;
use strict;
my $package = 'Foo';
my @names = $package->get_names;
Ответ 2
Строгая проверка помешает вам использовать переменную (или литеральную строку) как часть имени, но это можно отключить локально:
my @values;
{
no strict 'refs';
@values = @{"Mypackage"}::var;
}