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

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

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

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

Damian Conway

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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







12.24. String Comparisons


Prefer fixed-string eq comparisons to fixed-pattern regex matches .


If you're trying to compare a string against a fixed number of fixed keywords, the temptation is to put them all inside a single regex, as anchored alternatives:



# Quit command has several variants...

last COMMAND if $cmd =~ m{\A (?: q | quit | bye ) \z}xms;

The usual rationale for this is that a single, highly optimized regex match must

surely be quicker than three separate eq tests:



# Quit command has several variants...

last COMMAND if $cmd eq 'q'
|| $cmd eq 'quit'
|| $cmd eq 'bye';

Unfortunately, that's not the case. Regex-matching against a series of fixed alternations is at least 20% slower than individually eq-matching the same stringsnot to mention the fact that the eq-based version is significantly more readable.

Likewise, if you're doing a pattern match merely to get case insensitivity:



# Quit command is case-insensitive...

last COMMAND if $cmd =~ m{\A quit \z}ixms;

then it's more efficient, and arguably more readable, to write:



# Quit command is case-insensitive...

last COMMAND if lc($cmd) eq 'quit';

Sometimes, if there are a large number of possibilities to test:


Readonly my @EXIT_WORDS => qw(
q quit bye exit stop done last finish aurevoir
);

or the number of possibilities is indeterminate at compile time:


Readonly my @EXIT_WORDS
=> slurp $EXIT_WORDS_FILE, {chomp=>1};

then a regex might seem like a better alternative, because it can easily be built on the fly:


Readonly my $EXIT_WORDS => join '|', @EXIT_WORDS;
# Quit command has several variants...
last COMMAND if $cmd =~ m{\A (?: $EXIT_WORDS ) \z}xms;

But, even in these cases, eq offers a cleaner (though now slower) solution:


use List::MoreUtils qw( any );

# Quit command has several variants...

last COMMAND if any { $cmd eq $_ } @EXIT_WORDS;

Of course, in this particular case, an even better solution would be to use table look-up instead:


Readonly my %IS_EXIT_WORD
=> map { ($_ => 1) } qw(
q quit bye exit stop done last finish aurevoir
);

# and later...
# Quit command has several variants...

last COMMAND if $IS_EXIT_WORD{$cmd};


/ 317