Web Developer's Virtual Library: Encyclopedia of Web Design Tutorials, Articles and Discussions


WDVL Newsletter

Active Server Pages
JSP/Java Servlets
Microsoft SQL Server
Daily Backup
Dedicated Servers
Streaming Audio/Video
24-hour Support    

jobs.webdeveloper.com

Hiermenus


e-commerce
Partner With Us















Developer Channel
FlashKit.com
JavaScript.com
JavaScriptSource
Developer Jobs
ScriptSearch
StreamingMediaWorld
Web Developer's Journal
Web Developer's Virtual Library
WebDeveloper.com
Webreference
Web Hosts
XMLfiles.com

internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


Prototyping Code References - Page 16

July 13, 2001

Other than $, @ (and the synonymous %), we can supply one other basic prototype character: &. This tells Perl that the parameter to be supplied is a code reference to an anonymous subroutine. This is not as far-fetched as it might seem; the sort function accepts such an argument, for example.

Here is how we could prototype the do_list subroutine we introduced when we covered anonymous subroutines earlier:

sub do_list (&@) {
  my ($subref, @in) = @_;
  my @out;
  foreach (@in) {
  push @out, &$subref ($_);
  }
  return @out;
}

The prototype requires that the first argument be a code reference, since the subroutine cannot perform any useful function on its own. Either a subroutine reference or an explicit block will satisfy the prototype; for example:

@words = ("ehT", "terceS", "egasseM");
do_list {print reverse($_[0] =~/./g), "\n"} @words;

Note how this syntax is similar to the syntax of Perl's built-in sort, map, and grep functions.

Subroutines as Scalar Operators

We mentioned previously that subroutines can be thought of as user-defined list operators, and used much in the same way as built-in functions (that also work as list operators) like print, chomp, and so on. However, not all of Perl's functions are list operators. Some, such as abs, only work on scalars, and interpret their argument in a scalar context (or simply refuse to execute) if we try to supply a list.

Defining subroutines with a prototype of ($) effectively converts them from being list operators to scalar operators. Returning to our capitalize example, if we decided that, instead of allowing it to work on lists, we want to force it to only work on scalars, we would write it like this:

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

However, there is a sting in the tail. Before the prototype was added this subroutine would accept a list and capitalize the string in the first element, coincidentally returning it at the same time. Another programmer might be using it in the following way, without our knowledge:

capitalize (@list);

While adding the prototype prevents multiple strings being passed in a list, an array variable still fits the prototype, as we saw earlier. Suddenly, the previously functional capitalize turns the passed array into a scalar number:

@countries = ("england", "scotland", "wales");
capitalize (@countries);

The result of this is that the number '3' is passed into capitalize. Since this is not a variable, it causes a syntax error when we try to assign to $_[0]. If we chose to return a result rather than modifying the passed argument, then the code would all be perfectly valid, but badly bugged. However, a program that is used to print 'England' might start printing '3' instead. This is more than a little confusing, and not intuitively easy to track down.

The key problem here is not that we are passing an array instead of a scalar, but that we are checking for a scalar value rather than a scalar variable, which is what we actually require. In the next section we will see how to do that.

Parameters (Continued) - Page 15
Professional Perl Programming
Requiring Variables Rather than Values - Page 17


Up to => Home / Authoring / Languages / Perl / ProPerl




Jupiter Online Media: internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and Jupiter Online Media

Jupitermedia Corporate Info


Legal Notices, Licensing, & Permissions, Privacy Policy.

Web Hosting | Newsletters | Tech Jobs | Shopping | E-mail Offers