Perl Anonymous Подпрограмма / Ошибка функции
У меня есть следующий кусок кода: (очень упрощенный для целей этого вопроса, но прекрасно иллюстрирует проблему, с которой я столкнулся)
#!/usr/bin/perl
use strict;
use warnings;
&outer;
my $connected_sub;
sub outer {
print "HELLO\n";
&$connected_sub;
$connected_sub = sub {
print "GOODBYE\n";
}
}
При запуске программа выдает этот вывод и ошибку:
HELLO
Use of uninitialized value in subroutine entry at subTesting line 13.
Can't use string ("") as a subroutine ref while "strict refs" in use at subTesting.pl line 13.
Я полностью пропускаю что-то здесь? Я не могу понять или понять, в чем проблема с этим.
4 ответа
$ Connected_sub не инициализируется. Попробуйте назначить анонимную подписку:
my $connected_sub = sub {
print "The code you need to run\n";
}
В определении и сбросьте код после вызова &$connected_sub
Это полный пример изменения:
#!/usr/bin/perl
use strict;
use warnings;
my $connected_sub = sub {
print "GOODBYE\n";
};
&outer;
sub outer
{
print "HELLO\n";
&$connected_sub;
}
Чтобы уточнить:
Определения подпрограмм происходят на этапе компиляции. Таким образом, такой код будет работать:
foo();
sub foo { print "No need to declare me before calling!"; }
Но присвоение на самом деле не происходит, пока не будет вызвана эта строка кода. Вот почему это не сработает:
my $foo;
&$foo();
$foo = sub { print "Foo hasn't been set to me when you try to call me." }
Я предполагаю, что здесь вы пытаетесь назначить анонимную переменную для переменной $connected_sub
, Это не хороший способ сделать это.
Вы берете пустую переменную, пытаетесь использовать ее как ссылку на код, назначаете ссылку на код, затем выходите из подпрограммы и затем объявляете переменную с my
, Не лучший порядок ведения дел.
Что вы, вероятно, хотите сделать, это вернуть значение, которое может быть присвоено переменной, например:
my $connected = outer();
$connected->();
sub outer {
print "HELLO\n";
my $sub = sub { print "GOODBYE\n"; }
return $sub;
}
Я думаю, что использование лексической переменной внутри подпрограммы несколько сбивает с толку. Помимо общих недостатков использования глобальных переменных, подпрограмма также компилируется перед выполнением кода и объявлением переменной.
Кроме того, при вызове подпрограммы стандартный способ сделать это
name(@args);
куда @args
это ваш список аргументов. С помощью &
Это старый стиль Perl, и его использование имеет особое значение (переопределение прототипов). При использовании анонимного подпрограммы в переменной используйте ->()
нотации.
Похоже, вы используете $connected_stub
до его инициализации. Попробуйте переместить инициализацию вверх, например:
$connected_sub = sub {
print "GOODBYE\n";
}
&$connected_sub;