Perl
  Home arrow Perl arrow Introduction to mod_perl (part 5): More Perl Basics
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PERL

Introduction to mod_perl (part 5): More Perl Basics
By: Stas Bekman
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 5
    2003-03-12


    Table of Contents:
  • Introduction to mod_perl (part 5): More Perl Basics
  • my() Scoped Variable in Nested Subroutines
  • When You Cannot Get Rid of The Inner Subroutine
  • perldoc's Rarely Known But Very Useful Options
  • References

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    Introduction to mod_perl (part 5): More Perl Basics
    ( Page 1 of 5 )

    In this article we continue to talk about the essential Perl basics, that you should know before starting to program for mod_perl.

    Sometimes it's very hard to understand what a warning is complaining about. You see the source code, but you cannot understand why some specific snippet produces that warning. The mystery often results from the fact that the code can be called from different places if it's located inside a subroutine.

    Here is an example:

      warnings.pl
      -----------
      #!/usr/bin/perl -w
    
    
      use strict;
    
      correct();
      incorrect();
    
      sub correct{
        print_value("Perl");
      }
    
      sub incorrect{
        print_value();
      }
    
      sub print_value{
        my $var = shift;
        print "My value is $var\n";
      }

    In the code above, print_value() prints the passed value. Subroutine correct() passes the value to print, but in subroutine incorrect() we forgot to pass it. When we run the script:

      % ./warnings.pl

    we get the warning:

      Use of uninitialized value at ./warnings.pl line 16.

    Perl complains about an undefined variable $var at the line that attempts to print its value:

      print "My value is $var\n";

    But how do we know why it is undefined? The reason here obviously is that the calling function didn't pass the argument. But how do we know who was the caller? In our example there are two possible callers, in the general case there can be many of them, perhaps located in other files.

    We can use the caller() function, which tells who has called us, but even that might not be enough: it's possible to have a longer sequence of called subroutines, and not just two. For example, here it is sub third() which is at fault, and putting sub caller() in sub second() would not help us very much:

      sub third{
        second();
      }
      sub second{
        my $var = shift;
        first($var);
      }
      sub first{
        my $var = shift;
       print "Var = $var\n"
      }

    The solution is quite simple. What we need is a full calls stack trace to the call that triggered the warning.

    The Carp module comes to our aid with its cluck() function. Let's modify the script by adding a couple of lines. The rest of the script is unchanged.

      warnings2.pl
      -----------
      #!/usr/bin/perl -w
    
    
      use strict;
      use Carp ();
      local $SIG{__WARN__} = \&Carp::cluck;
    
      correct();
      incorrect();
    
      sub correct{
        print_value("Perl");
      }
    
      sub incorrect{
        print_value();
      }
    
      sub print_value{
        my $var = shift;
        print "My value is $var\n";
      }

    Now when we execute it, we see:

      Use of uninitialized value at ./warnings2.pl line 19.
        main::print_value() called at ./warnings2.pl line 14
        main::incorrect() called at ./warnings2.pl line 7

    Take a moment to understand the calls stack trace. The deepest calls are printed first. So the second line tells us that the warning was triggered in print_value(); the third, that print_value() was called by subroutine, incorrect().

      script => incorrect() => print_value()

    We go into incorrect() and indeed see that we forgot to pass the variable. Of course when you write a subroutine like print_value it would be a good idea to check the passed arguments before starting execution. We omitted that step to contrive an easily debugged example.

    Sure, you say, I could find that problem by simple inspection of the code!

    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.



     
     
    >>> More Perl Articles          >>> More By Stas Bekman
     

       

    PERL ARTICLES

    - Basic Charting with Perl
    - Using Getopt::Long: More Command Line Option...
    - Command Line Options in Perl: Using Getopt::...
    - Web Access with LWP
    - More Templating Tools for Perl
    - Site Layout with Perl Templating Tools
    - Build a Perl RSS Aggregator with Templating ...
    - Looping, Security, and Templating Tools
    - Perl: Bon Voyage Lists and Hashes
    - Templating Tools
    - Perl: Number Crunching
    - Perl Debuggers in Detail
    - Debugging Perl
    - Perl: More on Lists and Hashes
    - Perl: Dimensional Lists





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway
    Stay green...Green IT