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

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

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

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

Damian Conway

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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







4.15. Thin Commas


Don't use commas to sequence statements .


Perl programmers from a C/C++ background are used to writing C-style for loops in Perl:


# Binary chop search...
SEARCH:
for ($min=0,$max=$#samples, $found_target=0; $min<=$max; ) {
$pos = int(($max+$min)/2);
my $test_val = $samples[$pos];
if ($target == $test_val) {
$found_target = 1;
last SEARCH;
}
elsif ($target < $test_val) {
$max = $pos-1;
}
else {
$min = $pos+1;
}
}

Each comma within the for initialization acts as a kind of "junior semicolon", separating substatements within the first compartment of the for.

After seeing commas used that way, people sometimes think that it's also possible to use "junior semicolons" within a list:


print 'Sir ',
(check_name($name), $name),
', KBE';

The intent seems to be to check the person's name just before it's printed, with check_name( ) tHRowing an exception if the name is wrong (see Chapter 13). The underlying assumption is that using a comma would mean that only the final value in the parentheses was passed on to print.

Unfortunately, that's not what happens. The comma actually has two distinct roles in Perl. In a scalar context, it is (as those former C programmers expect) a sequencing operator: "do this, then do that". But in a list context, such as the argument list of a print, the comma is a list

separator , not technically an operator at all.

The subexpression (check_name($name), $name) is merely a sublist. And a list context automatically flattens any sublists into the main list. That means that the previous example is the same as:


print 'Sir ',
check_name($name),
$name,
', KBE';

which will probably not produce the desired effect:


Sir 1Tim Berners-Lee, KBE

The best way to avoid such problems is to adopt a style that limits commas to a single role: that of separating the items of lists. Then there can be no confusion between scalar comma operators and list comma separators.

If two or more statements need to be treated as a single statement, don't use scalar commas as "junior semicolons". Instead, use a do block and real semicolons:


# Binary chop search...

SEARCH:
for (do{$min=0; $max=$#samples; $found_target=0;}; $min<=$max; ) {
# etc, as before

}
print 'Sir ',
do{ check_name($name); $name; },
', KBE';

Or, better still, find a way to factor the sequence of statements out of the expression entirely:


($min, $max, $found_target) = (0, $#samples, 0);
SEARCH:
while ($min<=$max) {

# [Binary chop implementation as shown earlier]

}
check_name($name);
print "Sir $name, KBE";


/ 317