I confess that I don’t use the ‘-w’ flag much in Perl except when I do syntax checking like: $ perl -wc [script]

For the most part, the only warning perl issued during runtime for my programs ‘Use of uninitialized value …’, which is a pretty lame warning since Perl defines new created variables to be, er, undefined. In C, you sure as heck don’t want to be counting on any uninitialed variable values. Perl does the right thing, however, and that’s why we use it.

Today, I found a Perl “feature” that I nearly reported as a bug. Take a look at this code:

use strict;

print "end\n";

sub bar {
  for ($_[0]) {

    /[a-z]/ && do {
      print "Plunging into foo()\n";
      print "You got me!\n";
      return 1;


  print "fall through\n";

  return 1;

sub foo {

  my $ans = '';
  print "type 'q' to quit\n";
    last if lc (substr($ans, 0, 1)) eq 'q';
    print "\nstill in loop\n";
  } while( $ans = <> );


Earlier today, I would have expected this program to print:

Plunging into foo()
type 'q' to quit

You got me

This expectation would have also gone unfulfilled, since the real output is more like:

Plunging into foo()
type 'q' to quit

still in loop

fall through

What’s going on here? It looks like the ‘last’ in foo() is jumping back to the loop in bar(). In fact, this is the case and -w provides some insight:

Exiting subroutine via last at ...

Kudos to p5p for adding this warning! I suspect the problem lies with the infrequently-seen-in-Perl-but-useful-Pascal construction ‘do{}while()’. Since I haven’t run into this behavior before and I rarely use ‘do{}while(),’ I’m pointing fingers at it. Still this behavior seems a little bold to me. What do you think?

[Original use.perl.org post and comments.]