Previous Page
Next Page

5.4. Initialization

Initialize any variable you localize.

Many people seem to think that a localized variable keeps its pre-localization value. It doesn't. Whenever a variable is localized, its value is reset to undef[*].

[*] Or, more accurately, the storage associated with the variable's name is temporarily replaced by a new, uninitialized storage.

So this probably won't work as expected:

    use YAML;
    # Localize the current value...    (No it doesn't!)
    local $YAML::Indent;

    # Then change it, if necessary...
    if (defined $config{indent}) {
        $YAML::Indent = $config{indent};

Unless the if statement executes, the localized copy of $YAML::Indent will retain its post-localization value of undef.

To correctly localize a package variable but still retain its pre-localization value, you need to write this instead:

    use YAML;
# Localize the current value...
local $YAML::Indent = $YAML::Indent;
# Then change it, if necessary...
if (defined $config{indent}) { $YAML::Indent = $config{indent}; }

This version might look odd, redundant, and very possibly wrong, but it's actually both correct and necessary[*]. As with any other assignment, the righthand side of the localized assignment is evaluated first, yielding the original value of $YAML::Indent. Then the variable is localized, which installs a new container inside $YAML::Indent. Finally, the assignmentof the old value to the new containeris performed.

[*] Okay, so it still looks odd. Two out of three ain't bad.

Of course, you may not have wanted to preserve the former indentation value, in which case you probably needed something like:

    Readonly my $DEFAULT_INDENT => 4;

# and later...
use YAML; local $YAML::Indent = $DEFAULT_INDENT;

Even if you specifically did want that variable to be undefined, it's better to say so explicitly:

    use YAML;
    local $YAML::Indent = undef;

That way any readers of the code can immediately see that the lack of definition is intentional, rather than wondering whether it's an oversight.

    Previous Page
    Next Page