sub hanoi { my $move_disk = pop(@_); local *_hanoi = sub { my ( $n, $start, $end, $extra ) = @_; if ( $n == 1 ) { $move_disk->( 1, $start, $end ); } else { _hanoi( $n - 1, $start, $extra, $end ); $move_disk->( $n, $start, $end ); _hanoi( $n - 1, $extra, $end, $start ); } }; &_hanoi; } hanoi( $disk, 'A', 'B', 'C', \&check_move ); hanoi( $disk, 'A', 'B', 'C', \&hprint );