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/