Perl Best Practices [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Perl Best Practices [Electronic resources] - نسخه متنی

Damian Conway

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







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.


/ 317