Как я могу условно использовать модуль в Perl?
Я хочу сделать что-то подобное в Perl:
$Module1="ReportHashFile1"; # ReportHashFile1.pm
$Module2="ReportHashFile2"; # ReportHashFile2.pm
if(Condition1)
{
use $Module1;
}
elsif(Condition2)
{
use $Module2;
}
ReportHashFile *.pm содержит пакет ReportHashFile *.
Также как ссылаться на массив внутри модуля на основе имени динамического модуля?
@Array= @$Module1::Array_inside_module;
В любом случае я могу это достичь. Какая-то директива компилятора?
Ответы
Ответ 1
Вы можете найти полезный для этого if
.
В противном случае основной идеей является использование require
, которое происходит во время выполнения, вместо use
, которое происходит во время компиляции. Обратите внимание, что '
BEGIN {
my $module = $condition ? $Module1 : $Module2;
my $file = $module;
$file =~ s[::][/]g;
$file .= '.pm';
require $file;
$module->import;
}
Что касается адресации глобальных переменных, может быть проще, если вы просто экспортируете переменную или функцию, возвращающую ее вызывающему, которую вы можете использовать по ее неквалифицированному имени. В противном случае существует возможность использования метода и называть его $Module->method_name
.
В качестве альтернативы вы можете использовать символические ссылки, как описано в perlref
. Однако, это обычно довольно запах кода.
my @array = do {
no strict 'refs';
@{ ${ "${Module}::Array_inside_module" } };
};
Ответ 2
Если скорость выполнения важна, вы можете использовать строку eval:
if (Condition1) {
eval "use $Module1"; die [email protected] if [email protected];
}
elsif (Condition2) {
eval "use $Module2"; die [email protected] if [email protected];
}
Ответ 3
Люди уже рассказали вам, как вы можете загрузить модуль с помощью примитивов Perl. Там также Module:: Load:: Conditional.
Если вы хотите получить доступ к массиву с тем же именем независимо от того, какой модуль вы загрузили, подумайте над тем, чтобы сделать способ для этого, чтобы вы могли пропустить символическую ссылку. Дайте каждому модулю метод с тем же именем:
package ReportHashFileFoo;
our @some_package_variable;
sub get_array { \@some_package_variable }
Затем, когда вы загружаете этот модуль:
if( ... some condition ... ) {
eval "use $module" or croak ...;
my $array_ref = $module->get_array;
}
Я не знаю, что вы на самом деле делаете (проблема XY), но, вероятно, лучший дизайн. Когда вещи кажутся сложными, как это, это обычно потому, что вы не замечаете лучшего способа сделать это.