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;
Другие вопросы по тегам