473,323 Members | 1,547 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

Error when using coderefs.

Hello,

I am trying some code from Higher Order Perl by Mark Jason Dominus and it doesn't work. When I tried to replace the original print statements with a reference to a subroutine (print_instruction) that prints, I kept getting the error message "Undefined subroutine &main:: called at hanoi.pl line 27." Line 27 is marked in the code below in a comment (it shows as line 21 in the posting below). It doesn't like the dereferencing of the subroutine reference I passed in. This was cut and pasted from his website. The only things I added were the print_instruction subroutine and its calls, going strictly by what's in the book.

I am using Perl 5.8.8, ActiveState build 820, built Jan. 23, 2007 on Windows XP.

Expand|Select|Wrap|Line Numbers
  1. # hanoi(N, start, end, extra)
  2. # Solve Tower of Hanoi problem for a tower of N disks,
  3. # of which the largest is disk #N.  Move the entire tower from
  4. # peg 'start' to peg 'end', using peg 'extra' as a work space
  5.  
  6. sub print_instruction
  7. {
  8.     my ($disk, $start, $end) = @_;
  9.  
  10.     print "Move disk #$disk from $start to $end.\n";
  11. }
  12.  
  13. hanoi(3, 'A', 'C', 'B', \&print_instruction);
  14.  
  15. sub hanoi
  16. {
  17.     my ($n, $start, $end, $extra, $move_disk) = @_;
  18.  
  19.     if ($n == 1)
  20.     { 
  21.         $move_disk->(1, $start, $end);  # line 27
  22.     } 
  23.     else 
  24.     {
  25.         hanoi($n-1, $start, $extra, $end);             # Step 2
  26.         $move_disk->($n, $start, $end);
  27.         hanoi($n-1, $extra, $end, $start);             # Step 4
  28.     }
  29. }
  30.  
  31. sub print_instruction
  32. {
  33.     my ($disk, $start, $end) = @_;
  34.  
  35.     print "Move disk #$disk from $start to $end.\n";
  36. }
  37.  
Feb 28 '08 #1
4 1385
Oops, please don't be put off in the above post by the fact that I have two print_instruction subroutines defined. This is not the case in practice. I just copied that code above the call to hanoi() without deleting it from below. Thanks.
Feb 28 '08 #2
KevinADC
4,059 Expert 2GB
Hello,

I am trying some code from Higher Order Perl by Mark Jason Dominus and it doesn't work. When I tried to replace the original print statements with a reference to a subroutine (print_instruction) that prints, I kept getting the error message "Undefined subroutine &main:: called at hanoi.pl line 27." Line 27 is marked in the code below in a comment (it shows as line 21 in the posting below). It doesn't like the dereferencing of the subroutine reference I passed in. This was cut and pasted from his website. The only things I added were the print_instruction subroutine and its calls, going strictly by what's in the book.

I am using Perl 5.8.8, ActiveState build 820, built Jan. 23, 2007 on Windows XP.

Expand|Select|Wrap|Line Numbers
  1. # hanoi(N, start, end, extra)
  2. # Solve Tower of Hanoi problem for a tower of N disks,
  3. # of which the largest is disk #N.  Move the entire tower from
  4. # peg 'start' to peg 'end', using peg 'extra' as a work space
  5.  
  6. sub print_instruction
  7. {
  8.     my ($disk, $start, $end) = @_;
  9.  
  10.     print "Move disk #$disk from $start to $end.\n";
  11. }
  12.  
  13. hanoi(3, 'A', 'C', 'B', \&print_instruction);
  14.  
  15. sub hanoi
  16. {
  17.     my ($n, $start, $end, $extra, $move_disk) = @_;
  18.  
  19.     if ($n == 1)
  20.     { 
  21.         $move_disk->(1, $start, $end);  # line 27
  22.     } 
  23.     else 
  24.     {
  25.         hanoi($n-1, $start, $extra, $end);             # Step 2
  26.         $move_disk->($n, $start, $end);
  27.         hanoi($n-1, $extra, $end, $start);             # Step 4
  28.     }
  29. }
  30.  
  31. sub print_instruction
  32. {
  33.     my ($disk, $start, $end) = @_;
  34.  
  35.     print "Move disk #$disk from $start to $end.\n";
  36. }
  37.  
I don't see a problem with the code and It works for me. This is the correct syntax to use with a code reference:

$move_disk->(1, $start, $end)

So I am not sure what the problem is.
Feb 29 '08 #3
Below I post the answer as given me by Mark Jason Dominus, the author of "Higher Order Perl" himself. This is the complete text of his reply to my e-mail, quoted here with permission. His reply not only includes the correction to my code, but in doing so clearly explains the cryptic error message as well. I wanted to post it as warning of the kinds of problems one can run into when using recursion if one is not careful.


> I posted this on the web with the code and got only one response. He said
> that he saw nothing wrong with it and that it worked for him.

if he says it worked for him, he's lying.

Here's the problem. hanoi() now takes five arguments.

Here you call it with five arguments:

> hanoi(3, 'A', 'C', 'B', \&print_instruction);

And here it prepares to receive the five arguments:

> sub hanoi
> {
> my ($n, $start, $end, $extra, $move_disk) = @_;


But here you call it with only four arguments:

> hanoi($n-1, $start, $extra, $end); # Step 2
> $move_disk->($n, $start, $end);
> #print "Move disk #$n from $start to $end.\n"; # Step 3
> hanoi($n-1, $extra, $end, $start); # Step 4


So after the first call, the subsequent calls to hanoi() leave
$move_disk undefined.
Mar 5 '08 #4
KevinADC
4,059 Expert 2GB
Below I post the answer as given me by Mark Jason Dominus, the author of "Higher Order Perl" himself. This is the complete text of his reply to my e-mail, quoted here with permission. His reply not only includes the correction to my code, but in doing so clearly explains the cryptic error message as well. I wanted to post it as warning of the kinds of problems one can run into when using recursion if one is not careful.


> I posted this on the web with the code and got only one response. He said
> that he saw nothing wrong with it and that it worked for him.

if he says it worked for him, he's lying.

Here's the problem. hanoi() now takes five arguments.

Here you call it with five arguments:

> hanoi(3, 'A', 'C', 'B', \&print_instruction);

And here it prepares to receive the five arguments:

> sub hanoi
> {
> my ($n, $start, $end, $extra, $move_disk) = @_;


But here you call it with only four arguments:

> hanoi($n-1, $start, $extra, $end); # Step 2
> $move_disk->($n, $start, $end);
> #print "Move disk #$n from $start to $end.\n"; # Step 3
> hanoi($n-1, $extra, $end, $start); # Step 4


So after the first call, the subsequent calls to hanoi() leave
$move_disk undefined.
Well, he is also wrong, because here is your original code (less the duplicate function):

Expand|Select|Wrap|Line Numbers
  1. sub print_instruction
  2. {
  3.     my ($disk, $start, $end) = @_;
  4.  
  5.     print "Move disk #$disk from $start to $end.\n";
  6. }
  7.  
  8. hanoi(1, 'A', 'C', 'B', \&print_instruction);
  9.  
  10. sub hanoi
  11. {
  12.     my ($n, $start, $end, $extra, $move_disk) = @_;
  13.  
  14.     if ($n == 1)
  15.     { 
  16.         $move_disk->(1, $start, $end);  # line 27
  17.     } 
  18.     else 
  19.     {
  20.         hanoi($n-1, $start, $extra, $end);             # Step 2
  21.         $move_disk->($n, $start, $end);
  22.         hanoi($n-1, $extra, $end, $start);             # Step 4
  23.     }
  24. }
  25.  
It works just like that, all I did was change the 3 to a 1 here:

hanoi(1, 'A', 'C', 'B', \&print_instruction);

I admit I did not go far enough to test the code, but the author calling me a liar seems rather obtuse. My test was just faulty in that all I did was confim the coderef worked the way you had it, I was not testing the logic of your code for all errors. So forgive me for not being thorough, but I answer many questions on many forums and I sometimes am too hasty.
Mar 5 '08 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Wayno | last post by:
My php logs are coming up empty. I have done all I can think of, and all that made sense to me. Can someone take a look at my php.ini please and tell me what you think may be the problem. I...
6
by: Peter Frost | last post by:
Please help I don't know if this is possible but what I would really like to do is to use On Error Goto to capture the code that is being executed when an error occurs. Any help would be much...
9
by: JTrigger | last post by:
When I compile my project using the IDE on a development machine it works just fine. When I compile it on the server using csc.exe, I get the following error when I try to bring it up in the web...
10
by: Shawn | last post by:
JIT Debugging failed with the following error: Access is denied. JIT Debugging was initiated by the following account 'PLISKEN\ASPNET' I get this messag in a dialog window when I try to open an...
6
by: jasn | last post by:
Hello I am getting the following error message when I try and send an XML sting to a web service, I read somewhere that most web services prefer ascii and some throw errors when using unicode so...
3
by: Ted | last post by:
In WSAT, I get the following error when trying to set up my provider: Could not establish a connection to the database. If you have not yet created the SQL Server database, exit the Web Site...
2
hyperpau
by: hyperpau | last post by:
Before anything else, I am not a very technical expert when it comes to VBA coding. I learned most of what I know by the excellent Access/VBA forum from bytes.com (formerly thescripts.com). Ergo, I...
0
hyperpau
by: hyperpau | last post by:
Before anything else, I am not a very technical expert when it comes to VBA coding. I learned most of what I know by the excellent Access/VBA forum from bytes.com (formerly thescripts.com). Ergo, I...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.