Perl's Special Named Code Blocks

If you read perlmod's "BEGIN, UNITCHECK, CHECK, INIT, and END", you'll learn that Perl has several special named code blocks that let you run arbitrary code at various points in the compilation and execution process.

David Mertens wrote about this recently in Lexical closures with END blocks warn, but Just Work. His post explains a couple of features of these blocks but doesn't tell the entire story.

These code blocks are code blocks in the same way that function definitions are code blocks. They exist in lexical environments. They provide their own lexical environments. They don't get stored in the symbol table the way you might expect a normal function does, but they have their lexical bindings created and fixed up in the same way that named functions do. In fact, you can just as easily write them:

sub BEGIN { say 'In first BEGIN'  }
BEGIN     { say 'In second BEGIN' }

The declaration is the same either way. That ought to make the behavior David wrote about more clear; the error message he saw is the same as the one you get when you declare a function within another function. Yes, the inner function will close over the lexical scope of the first function, but they won't share inner lexicals. If you've done much work with closures in Perl, that ought to make sense to you.

You might find this surprising though:

#!/usr/bin/env perl

use Modern::Perl;

exit main( @ARGV );

sub main {

    foo();
    bar();
    baz();
    Foo->new;
    return 0;
}

AUTOLOAD {
    our $AUTOLOAD;
    say "Hit autoload for $AUTOLOAD";
}

package Foo;

sub new { bless {}, $_[0] }
DESTROY { say 'Destroying!' }

Perl's tokenizer (toke.c in the Perl source code tree) has special cases for the five special code blocks as well as AUTOLOAD and DESTROY. This allows you to provide or elide the leading sub from the declaration of any of the five code blocks, the AUTOLOAD function, or the DESTROY method—though for the sake of clarity, you should probably use sub on the latter two and not on the former five.

(You may be able to make the philosophical argument to treat these seven code blocks in the same way because they never get called directly with arguments; in most normal code, you expect Perl's runtime to call them implicitly. That falls apart only a little bit because a subclass's DESTROY might want to redispatch upward, but Moose's DEMOLISH strategy solves that anyhow.)

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

affiliated with ModernPerl.net

Categories

Pages

About this Entry

This page contains a single entry by chromatic published on January 21, 2014 6:00 AM.

How to Rewrite Software without Destroying Your Business was the previous entry in this blog.

Fatal Warnings are a Ticking Time Bomb is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.


Sponsored by Blender Recipe Reviews and the Trendshare how to invest guide

Powered by the Perl programming language

what is programming?