Perl
  Home arrow Perl arrow Introduction to mod_perl (part 5): Mor...
Dev Shed Forums 
Administration  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
IBM Rational Software Development Conference
 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: 4 stars4 stars4 stars4 stars4 stars / 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:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb 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

    TestComplete™ automates software testing for a fraction of what the big guys charge. Easy functional and load testing for all Windows, .NET, Java and Web apps. Download a free trial now.

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

    Sometimes it's very hard to understand what a warning is complainingabout. You see the source code, but you cannot understand why somespecific snippet produces that warning. The mystery often results fromthe fact that the code can be called from different places if it'slocated 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. Subroutinecorrect() passes the value to print, but in subroutine incorrect() weforgot 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 thatattempts to print its value:

    print "My value is $var\n";

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

    We can use the caller() function, which tells who has called us, buteven that might not be enough: it's possible to have a longer sequenceof called subroutines, and not just two. For example, here it is subthird() 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 traceto the call that triggered the warning.

    The Carp module comes to our aid with its cluck() function. Let'smodify the script by adding a couple of lines. The rest of the scriptis 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 callsare printed first. So the second line tells us that the warning wastriggered in print_value(); the third, that print_value() wascalled by subroutine, incorrect().

    script => incorrect() => print_value()

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

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

    Well, you're right. But I promise you that your task would be quitecomplicated and time consuming if your code has some thousands oflines. In addition, under mod_perl, certain uses of the evaloperator and ``here documents'' are known to throw off Perl's linenumbering, so the messages reporting warnings and errors can haveincorrect line numbers. This can be easily fixed by helping compilerwith #line directive. If you put the following at the beginning ofthe line in your script:

    #line 125

    it will tell the compiler that the next line is number 125 forreporting needs. Of course the rest of the lines would be adapted aswell.

    Getting the trace helps a lot.

    More Perl Articles
    More By Stas Bekman


     

       

    PERL ARTICLES

    - Perl: Another Round with Hashes
    - Perl Hashes
    - Perl Lists: A Final Look at List::Util
    - Perl Lists: Utilizing List::Util
    - Perl Lists: The Split() Function
    - SQL and CGI with Perl and DBI
    - Perl Lists: More Functions and Operators
    - SELECT Queries and Perl
    - Perl Lists: More on Manipulation
    - Creating a Database with Perl and DBI
    - Perl: Sailing the List(less) Seas
    - Perl and DBI
    - Perl: Concatenating Text and More
    - Perl Text: Quoting Without Quote Marks
    - Perl: Releasing Your Inner Textuality




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway