Я читаю книгу Марка Джейсона Домина "Perl высшего порядка" и застрял на одном из первых примеров.Он вращается вокруг рекурсивного решения проблемы Ханойской башни, что отлично подходит для моей программы.Проблема в том, что книга развивает пример путем рефакторинга кода, где вместо того, чтобы просто печатать то, что делает решение, функция решения принимает другой параметр.Это функция, которая в моем случае просто делает то же самое.
Проблема в том, что я определил свою вспомогательную функцию и попытался передать ее по ссылке, а затем вызвать ее из главной функции,но я получаю следующую ошибку.
Невозможно использовать неопределенное значение в качестве ссылки на подпрограмму в строке main.pl 86.
Эта версия не принимаетфункция в качестве аргумента и правильно решает проблему.
#!/usr/bin/perl
use utf8;
use v5.26;
use strict;
use warnings;
sub SolveTowerOfHanoiProblem0 {
my ($n, $start, $end, $extra) = @_;
if ($n == 1) {
say "Move disk #$n from $start to $end.";
} else {
SolveTowerOfHanoiProblem0($n - 1, $start, $extra, $end);
say "Move disk #$n from $start to $end.";
SolveTowerOfHanoiProblem0($n - 1, $extra, $end, $start);
}
}
SolveTowerOfHanoiProblem0(3, 'A', 'C', 'B');
Вывод:
Move disk #1 from A to C.
Move disk #2 from A to B.
Move disk #1 from C to B.
Move disk #3 from A to C.
Move disk #1 from B to A.
Move disk #2 from B to C.
Move disk #1 from A to C.
Я хочу реорганизовать код, чтобы строка, которая выводит то, что происходит на каждом шаге, будетнезависимо от кода решения, поэтому на данный момент я написал другую функцию, которая просто делает то же самое, но передается вызывающей стороной в качестве аргумента:
sub SolveTowerOfHanoiProblem {
my ($n, $start, $end, $extra, $moveDisk) = @_;
if ($n == 1) {
$moveDisk->($n, $start, $end);
} else {
SolveTowerOfHanoiProblem($n - 1, $start, $extra, $end);
$moveDisk->($n, $start, $end);
SolveTowerOfHanoiProblem($n - 1, $extra, $end, $start);
}
}
sub PrintInstruction {
my ($disk, $start, $end) = @_;
say "Move disk #$disk from $start to $end.";
}
SolveTowerOfHanoiProblem(8, 'A', 'C', 'B', \&PrintInstruction);
Я получаю следующую ошибку времени выполнения: Can't use an undefined value as a subroutine reference at main.pl line 86
.Именно здесь я впервые вызываю переданную функцию.
Строка 86:
if ($n == 1) {
$moveDisk->($n, $start, $end); # <---- Here, Line 86
} else {
SolveTowerOfHanoiProblem($n - 1, $start, $extra, $end);
$moveDisk->($n, $start, $end);
Я не понимаю, почему вспомогательная ссылка будет неопределенной.Я определил функцию, на которую ссылаюсь, и из того, что я нашел до сих пор ( PerlMonks - Вызов подпрограммы по ссылке? ) Я, кажется, правильно вызываю функцию.
Я также рассмотрел этот вопрос , но моя функция PrintInstruction
не определена в модуле, она определена локально, поэтому, если я правильно понимаю, мне не нужен символ $
вссылка.
Что мне не хватает?