Приглашаем посетить
Майков (maykov.lit-info.ru)

Section 5.6.  Localizing Punctuation Variables

Previous
Table of Contents
Next

5.6. Localizing Punctuation Variables

If you're forced to modify a punctuation variable, localize it.

The problems described earlier under "Localization can also crop up whenever you're forced to change the value in a punctuation variable (often in I/O operations). All punctuation variables are global in scope. They provide explicit control over what would be completely implicit behaviours in most other languages: output buffering, input line numbering, input and output line endings, array indexing, et cetera.

It's usually a grave error to change a punctuation variable without first localizing it. Unlocalized assignments can potentially change the behaviour of code in entirely unrelated parts of your system, even in modules you did not write yourself but are merely using.

Using local is the cleanest and most robust way to temporarily change the value of a global variable. It should always be applied in the smallest possible scope, so as to minimize the effects of any "ambient behaviour" the variable might control:


    Readonly my $SPACE => q{};

    if (@ARGV) {
        local $INPUT_RECORD_SEPARATOR  = undef;   
# Slurp mode
local $OUTPUT_RECORD_SEPARATOR = $SPACE;
# Autoappend a space to every print
local $OUTPUT_AUTOFLUSH = 1;
# Flush buffer after every print

        # Slurp, mutilate, and spindle...
$text = <>; $text =~ s/\n/[EOL]/gxms; print $text; }

A common mistake is to use unlocalized global variables, saving and restoring their original values at either end of the block, like so:

    Readonly my $SPACE => q{};

    if (@ARGV) {
        my $prev_irs = $INPUT_RECORD_SEPARATOR;
        my $prev_ors = $OUTPUT_RECORD_SEPARATOR;
        my $prev_af  = $OUTPUT_AUTOFLUSH;

        $INPUT_RECORD_SEPARATOR  = undef;
        $OUTPUT_RECORD_SEPARATOR = $SPACE;
        $OUTPUT_AUTOFLUSH        = 1;

        $text = <>;
        $text =~ s/\n/[EOL]/gxms;
        print $text;

        $INPUT_RECORD_SEPARATOR  = $prev_irs;
        $OUTPUT_RECORD_SEPARATOR = $prev_ors;
        $OUTPUT_AUTOFLUSH        = $prev_af;

    }

This way is slower and far less readable. It's prone to cut-and-paste errors, mistyping, mismatched assignments, forgetting to restore one of the variables, or one of the other classic blunders. Use local instead.

    Previous
    Table of Contents
    Next