ServersThe Perl You Need to Know, Part II: Working with Nested Subroutines...

The Perl You Need to Know, Part II: Working with Nested Subroutines Page 2




Well, you’re right. But I promise you that your task would be quite
complicated and time consuming if your code has some thousands of lines. In
addition, under mod_perl, certain uses of the eval
operator and “here documents” are known to throw off Perl’s line
numbering, so the messages reporting warnings and errors can have incorrect
line numbers. This can be easily fixed by helping compiler with #line directive. If you put the following at the beginning of the line in your
script:

 #line 125

it will tell the compiler that the next line is number 125 for reporting needs. Of course the rest of the lines
would be adapted as well.

Getting the trace helps a lot.

my() Scoped Variable in Nested Subroutines

Before we proceed let's make the assumption that we want to develop the
code under the strict pragma. We will use lexically scoped variables (with help of the
my() operator) whenever it's possible.

The Poison

Let's look at this code:

  nested.pl
  -----------
  #!/usr/bin/perl
  
  use strict;
  
  sub print_power_of_2 {
    my  = shift;
  
    sub power_of_2 {
      return  ** 2; 
    }
  
    my  = power_of_2();
    print "^2 = n";
  }
  
  print_power_of_2(5);
  print_power_of_2(6);

Don't let the weird subroutine names fool you, the
print_power_of_2() subroutine should print the square of the
number passed to it. Let's run the code and see whether it works:

  % ./nested.pl
  
  5^2 = 25
  6^2 = 25

Ouch, something is wrong. May be there is a bug in Perl and it doesn't work
correctly with the number 6? Let's try again using 5 and 7:

  print_power_of_2(5);
  print_power_of_2(7);

And run it:

  % ./nested.pl
  
  5^2 = 25
  7^2 = 25

Wow, does it works only for 5? How about using 3 and 5:

  print_power_of_2(3);
  print_power_of_2(5);

and the result is:

  % ./nested.pl
  
  3^2 = 9
  5^2 = 9

Now we start to understand--only the first call to the
print_power_of_2() function works correctly. Which makes us
think that our code has some kind of memory for the results of the first
execution, or it ignores the arguments in subsequent executions.

The Diagnosis

Let's follow the guidelines and use the -w flag. Now execute the code:

  % ./nested.pl
  
  Variable "" will not stay shared at ./nested.pl line 9.
  5^2 = 25
  6^2 = 25

We have never seen such a warning message before and we don't quite
understand what it means. The diagnostics pragma will certainly help us. Let's prepend this pragma before the strict pragma in our code:

  #!/usr/bin/perl -w
  
  use diagnostics;
  use strict;

Latest Posts

Related Stories