אופרטורים#
Perl מאיית את האופרטורים הבוליאניים פעמיים, בשתי מחלקות קדימות שונות. הצורות הסימבוליות בסגנון C (&&, ||, !) נקשרות חזק; צורות המילה (and, or, not) נקשרות רפה מאוד. קיים גם // עבור הניב defined-or, xor עבור או־בלעדי, והשילוש ?: שהוא בחירה לוגית בתחפושת.
המצאי המלא#
אופרטור | נקרא | מחזיר | קדימות |
|---|---|---|---|
| not |
| גבוהה |
| and | שמאל אם שקר, אחרת ימין (ה־אופרנד) | גבוהה |
| or | שמאל אם אמת, אחרת ימין (ה־אופרנד) | גבוהה |
| defined-or | שמאל אם מוגדר, אחרת ימין (ה־אופרנד) | גבוהה |
| או בלעדי |
| נמוכה מאוד |
| not |
| נמוכה מאוד |
| and | שמאל אם שקר, אחרת ימין (ה־אופרנד) | נמוכה מאוד |
| or | שמאל אם אמת, אחרת ימין (ה־אופרנד) | נמוכה מאוד |
| שילוש | אמצע אם תנאי אמת, אחרת ימין (אופרנד) | נמוכה |
שני דברים בטבלה זו עושים את רוב העבודה:
&&ו־||מחזירים אופרנד, לא בוליאני. זוהי התכונה שמאפשרת לניבים של Perl לעבוד כפי שהם עובדים. ראו להלן.הצורות הסימבוליות וצורות המילה נבדלות בקדימות, לא במשמעות.
&&ו־andמחשבים את אותה פונקציה לוגית. הם נבדלים בעוצמת הקישור לאופרטורים סביבם. זו הסיבה שאתם רואיםor dieלאחר קריאות לפונקציות אך||בתוך ביטויים — הפרק על הניבor dieמסביר.
קיצור וכלל החזרת האופרנד#
&& ו־|| מחושבים משמאל לימין ועוצרים ברגע שהתוצאה נקבעת.
A && B— אםAהוא שקר, החזר אתAמבלי לחשב אתB. אחרת החזר אתB.A || B— אםAהוא אמת, החזר אתAמבלי לחשב אתB. אחרת החזר אתB.
חשוב מכך, ערך ההחזרה הוא האופרנד עצמו, לא אמת/שקר מנורמל. זה מה שמאפשר לתבניות כמו $config{port} || 8080 לעבוד: אם $config{port} מוגדר (אמיתי), הביטוי הוא ערכו של $config{port}; אם לא, הוא 8080.
my $port = $config{port} || 8080;
my $name = $user_input || "anonymous";
my $list = shift || [];
אותה תכונה מפעילה את or die:
open my $fh, '<', $path or die "open $path: $!";
# ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
# if open returns true, the right-hand operand
# the whole expression is never evaluated
# is true and we move on
open מחזיר אמת בהצלחה, undef בכישלון. בהצלחה הקיצור עוצר בשמאל ו־die לעולם לא רץ. בכישלון האופרנד הימני מחושב, שהוא הקריאה ל־die.
// — defined-or#
|| מתייחס ל־0, "", ו־"0" כמו ל־undef. לפעמים זה שגוי: 0 שהוגדר הוא ערך אמיתי, לא חסר. // מקצר על מוגדרוּת במקום על אמיתיוּת:
A // B— אםAמוגדר, החזר אתA. אחרת החזר אתB.
my $port = $config{port} || 8080; # 0 means "use default" — wrong
my $port = $config{port} // 8080; # 0 means "0", undef means "use default"
my $verbose = $opt{verbose} // 0; # 0 is a real choice
צורות ההשמה המורכבות ||= ו־//= חוסכות מכם לחזור על המשתנה בשמאל:
$config{port} //= 8080; # set only if currently undef
$cache{$key} ||= compute($key); # set if currently false
xor והיעדרה של צורה בעלת קדימות גבוהה#
אין ^^ ב־Perl. xor קיים רק כצורת מילה בעלת קדימות נמוכה־מאוד, ובניגוד ל־and/or הוא אינו מקצר (הוא לא יכול — שני הצדדים חייבים להיות מחושבים כדי לקבוע את התוצאה). הוא מחזיר 1 מנורמל או "", לא אופרנד.
if ($admin xor $guest) { ... } # exactly one of the two
עבור xor על ערכים ולא על אמיתיוּת, ה־^ הביטי חל על מספרים שלמים — מכוסה ב־פרק היישומים.
! ו־not#
שניהם שוללים. ! הוא הצורה הסימבולית בעלת הקדימות הגבוהה; not הוא צורת המילה בעלת הקדימות הנמוכה. שניהם מחזירים ערך מנורמל: 1 עבור ״האופרנד היה שקר״, מחרוזת ריקה "" עבור ״האופרנד היה אמת״.
my $missing = ! $config{port}; # 1 if port is unset/0/""/"0"
return if not @items; # cleaner reading than `if !@items`
השילוש ?:#
COND ? X : Y הוא בחירה לוגית: אם COND הוא אמת הערך הוא X, אחרת Y. זה לא רק תחביר מתוק עבור if/else משום שזהו ביטוי — יש לו ערך, ניתן להשמה, להחזרה, להעברה כארגומנט.
my $label = $count == 1 ? "1 item" : "$count items";
return $ok ? \%result : undef;
היזהרו מקינון: $a ? $b : $c ? $d : $e מנותח כ־$a ? $b : ($c ? $d : $e) — ?: משורשרים הם אסוציאטיביים מימין, מה שלרוב הוא מה שאתם רוצים עבור מפל if/elsif/else אך כדאי לדעת ולא לנחש.
מדוע צורות המילה קיימות: קדימות, לא סגנון#
|| נקשר חזק יותר מ־=. or נקשר רפה יותר מ־= (או ,, או כל דבר אחר בעל משקל מוסכם). זוהי כל הסיבה לקיומן של צורות המילה.
my $fh = open $h, '<', $path || die "no $path: $!";
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
# parses as: open $h, '<', ($path || die "no $path: $!")
# which is: open the file named "either $path or the die-message"
# which is: catastrophe.
my $fh = open $h, '<', $path or die "no $path: $!";
# parses as: ($fh = open $h, '<', $path) or die "no $path: $!"
# which does what you meant.
כלל אצבע:
בתוך ביטוי, שבו אתם רוצים שהערך יזרום לתוך משתנה או אופרטור אחר: השתמשו ב־
&&,||,!,//.לאחר משפט, שבו אתם רוצים שתופעת לוואי (
die,warn,return) תפעל בתנאי: השתמשו ב־or,and,not.
מה כדאי לזכור מהפרק הזה#
&&ו־||אינם פרדיקטים המחזירים 1 או 0 — הם מחזירים אחד מהאופרנדים שלהם. זהו היסוד של||,||=,or die, ושל רוב ניבי ברירת המחדל הקצרים.//הוא||עבור מוגדרוּת, לא אמיתיוּת. השתמשו בו כאשר0הוא ערך לגיטימי.צורות המילה קיימות כדי להיקשר רפה יותר מהשמה, לא לצרכי סגנון.
xorקיים, אין לו צורה סימבולית, אינו מקצר.
ראו גם#
perlop — לוגי — מלווה מדריך העיון, עם הקשר שורת הקדימות והערות ספציפיות ל־PetaPerl.
perlop — קדימות — הטבלה המלאה; שורות 5, 15, 16, 22, 23, 24 הן האופרטורים בעמוד זה.
perlop — שילוש —
?:כבחירה לוגית.