spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / perl / professional / chap7 / 3 To page 1To page 2current pageTo page 4
[previous] [next]

Professional Perl

Developer News
Mandrake Linux Founder Back, Virtually
Amazon: We're a Technology Company
Sun Expands MySQL With Closed Source

Converting Scalar Subroutines into List Processors

Consider this subroutine, which capitalizes the first letter of the string that it is passed:

sub capitalize {
   $_[0] = ucfirst(lc $_[0]);
   print "$_[0]";
}

$country = "england";
capitalize($country);   # produces 'England'

Simple enough, but it only works on one string at a time. However, just because we wrote this subroutine to work as a scalar operator does not alter the fact that in reality it is working on a list. We have just limited it to handle a list with one value. With only a little extra effort we can turn this subroutine into something that works on scalars and lists alike:

sub capitalize {
   foreach (@_) {
      $_ = ucfirst lc;   # lc uses $_ if argument is omitted
      print "$_[0]";
   }
}

Or more efficiently, with map:

sub capitalize {
   map {$_ = ucfirst lc} @_;
   print "$_[0]";
}

This version works identically for calls like the above that pass only one parameter, but also happily works on arrays too:

sub capitalize {
   map {$_ = ucfirst lc} @_;
   print "@_[0, 1, 2]";
}

@countries = ("england", "scotland", "wales");
capitalize (@countries);   # produces ("England", "Scotland", "Wales")

Passing '@_' Directly into Subroutines

We said earlier that the @_ array is distinct to each subroutine and masks any previous definition. That is almost true - there is one exception provided, for reasons of efficiency, to the Perl programmers dedicated to optimizing their code. Normally @_ is defined locally, on entry to each subroutine. So, if we pass in no parameters at all we get an empty array. However, if we call a subroutine using the & prefix and do not pass parameters or use braces then the subroutine inherits the @_ array of the calling subroutine directly:

&mysubroutine;   # inherit @_ from parent	

The problem with this technique is that it is rather arcane, and not obvious to the reader of our code. Therefore, if we use it, a comment to the effect that this is what we are doing (such as the one above) is highly recommended.

As far as the subroutine is concerned this is no different to passing the @_ array as a parameter:

mysubroutine(@_);

Although, this may seem equivalent, in the second case the @_ array is copied each time the call is made. If @_ contains a large number of values, or many calls are made (for instance in a recursive subroutine) then this is potentially expensive. The &mysubroutine; notation passes the @_ array directly, without making a copy, and so avoids the unnecessary work. Whether this is worth the trouble or not is of course another matter. If @_ only contains a few elements, it is probably better to live with the very minor inefficiency of copying the array and use the explicit version.

Note that the aliasing of the values in the @_ array to the original variables (if the parameter was a variable) happens in either case, so it is not necessary to resort to this practice if all we want to do is modify the variables that were passed to us.

home / programming / perl / professional / chap7 / 3 To page 1To page 2current pageTo page 4
[previous] [next]

Copyright 1999 Wrox Press Ltd. and

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

webref The latest from WebReference.com Browse >
Working with the DOM Stylesheets Collection · Administering RBAC in PHP 5 CMS Framework · xref: Automatic Cross Referencing Script
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Combine BottomCount() with Other MDX Functions to Add Sophistication · Creating a Daemon with Python · The Coming Voice-over-WiMAX Revolution


Revised: March 22, 2001
Created: March 22, 2001


URL: http://webreference.com/programming/perl/professional/chap7/3/