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

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

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

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

Damian Conway

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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







8.11. Globbing


Use glob, not <...> .


The <...> syntax is heavily associated with I/O in most people's minds. So something like this:


my @files = <*.pl>;

is easy to mistake for a normal readline operation:


my @files = <$fh>;

Unfortunately, the first version isn't an input operation at all. Angle brackets are input operators only when they're empty (<>), or when they contain a bareword identifier (<DATA>), or when they contain a simple scalar variable (<$input_file>). If anything else appears inside the angles, they perform shell-based directory look-up instead.

In other words, the <*.pl> operation takes the contents of the angle brackets (i.e., *.pl), passes them to the csh system shell[*], collects the list of filenames that match this shell pattern, and returns those names.

[*] Under more recent versions of Perl, the shell pattern is expanded by the interpreter itself. See the standard File::Glob module for details.


It's not bad enough that this "file glob" is easy to confuse with a popular I/O operation. Far worse, if you apply other best practices when writing itsuch as factoring the fixed shell pattern out into a named constantit suddenly transforms into the very I/O operation it previously only looked like:


Readonly my $FILE_PATTERN => '*.pl';
# and later...
my @files = <$FILE_PATTERN>; # KABOOM! (probably)

As mentioned earlier, a scalar variable in angles is one of the three valid forms that invoke a readline call in Perl, which means that the refactored operation

isn't a file glob specification any more. Instead, the angles attempt to do a readline, discover that $FILE_PATTERN contains the string '*.pl', and head straight off to the symbol table looking for a filehandle of that name. Unless the coder has been truly evil, there won't be such a filehandle[] and, instead of the expected file list appearing in @files, a 'readline( ) on unopened filehandle' exception will be thrown.

[] They would have to have written something like:


no strict 'refs'; open *{'*.pl'}, '<', $filename;

in which case the calamity that is about to befall them is a clear case of Instant Justice.


A construct that breaks when you attempt to improve its readability is, by definition, unmaintainable. The file globbing operation has a proper name:


my @files = glob($FILE_PATTERN);

Use it, and keep the angle brackets strictly for input operations.


/ 317