On 24 May 2010 11:49, Weizhong Dai <weizhong....@gmail.com> wrote:
> Hi guys, I met a problem.
> When I tried this script below:
>
> //--------------------------------------------------------------------
> sub print_instruction {
>  my ($disk, $start, $end) = @_;
>  print "Move disk #$disk from $start to $end.\n";
> }
>
> sub hanoi {
>  my ($n, $start, $end, $extra, $m) = @_;
>  if ($n == 1) {
>    $m->(1, $start, $end);
>  } else {
>    hanoi($n-1, $start, $extra, $end);
>    $m->($n, $start, $end);
>    hanoi($n-1, $extra, $end, $start);
>  }
> }
>
> &hanoi(3, 'A', 'C', 'B', \&print_instruction);
> //-------------------------------------------------------------------------
>
> I got a error : Undefined subroutine &main:: called at ....
> this is an example in <High Order Perl>, so it should not be wrong, I
> just don't known what is the problem.
> Plz help me.

You didn't "use strict". If you turn on use strict, the problem
becomes much clearer:

   Can't use string ("") as a subroutine ref while "strict refs" in
use at weizhong.pl line 10.

Line 10, in my copypasted script, is this:

   $m->(1, $start, $end);

$m is being used as a sub ref but it's complaining that $m is a
string. As Rob Coops accurately pointed out, this is because you
aren't passing enough arguments in the recursive call:

   hanoi($n-1, $start, $extra, $end);

So I have two questions for you:
1) Do you know about "use strict" and "use warnings"? do you aspire to
*always* use them?
2) Is this *really* the exact code from HOP? Does HOP make the same
mistake? If so, is it documented at the HOP errata page? If not, where
did you go wrong in copying from the book?

Incidentally, the original error message:

   Undefined subroutine &main:: called at ....

is caused by the same error. Without "use strict 'refs'", a string can
be used as a subref, so for example you can say:

   my $ref = 'foo';
   $ref->();  # same as foo();

$m is uninitialized, and its value is converted to the empty string
"", and then the subroutine in package "main" with name "" is called,
i.e. the subroutine "&main::". This subroutine doesn't exist, which
causes the error message seen.

If you "use warnings" as well, you also get the warning

   Use of uninitialized value in subroutine entry at ....

which warns you that $m is uninitialised.

Phil

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to