אופרטור השילוש#

אופרטור אחד, שלושה אופרנדים. בחירה לוגית כביטוי - לתוצאה יש ערך, ניתן להשים אותה, להחזיר אותה, להעביר אותה כארגומנט.

צורה#

COND ? THEN : ELSE

אם COND אמת, הערך הוא THEN; אחרת הוא ELSE. רק הענף הנבחר מוערך:

my $label = $count == 1 ? "1 item" : "$count items";
return $ok ? \%result : undef;
my $abs   = $x < 0     ? -$x       : $x;

זהו ביטוי, לא הוראה#

הסיבה הנפוצה ביותר להישען על ?: במקום if/else היא שאתם רוצים ערך - להשים, להחזיר, להציב בתוך ביטוי אחר:

# verbose
my $kind;
if ($n == 1) { $kind = 'singular' }
else         { $kind = 'plural'   }

# idiomatic
my $kind = $n == 1 ? 'singular' : 'plural';

שרשור (אסוציאטיבי לימין)#

A ? B : C ? D : E מפוענח כ־A ? B : (C ? D : E) - השרשרת יורדת דרך הענף השקרי:

my $sign = $x < 0  ? '-'
         : $x > 0  ? '+'
         :           '0';

הפריסה בעמודות הופכת את השרשרת לקריאה. מעבר לשתיים או שלוש רמות, עברו ל־if/elsif/else - השרשרת חדלה להיות ברורה יותר מהחלופה.

שילוש כ־lvalue#

שני הענפים חייבים להיות lvalues, והענף הנבחר הוא ה־lvalue שאליו אתם משימים:

my ($pos, $neg) = (0, 0);
($x > 0 ? $pos : $neg) = $x;             # assigns to $pos or $neg

# Common case: pick a buffer to append to
($verbose ? $log : $debug) .= "$msg\n";

תבנית זו נדירה בקוד מודרני - if מפורש עם שתי השמות פשוטות נקרא טוב יותר. כדאי להכיר למקרה שתיתקלו בה.

מה שאינכם כותבים#

?: אינו מפריד הוראות. אלה שגויים:

$x ? do_a() : do_b();                    # OK: do_a/do_b have side-effects,
                                         # but the value is discarded
$x > 0 ? print "yes\n" : print "no\n";   # WORKS, but reads strangely

כשהמטרה היא תופעת־לוואי (ולא ערך), השתמשו ב־if/else או ב־if/unless הפוסטפיקסיים:

$x > 0 ? do_yes() : do_no();             # value-return phrasing
do_yes() if $x > 0;                       # side-effect phrasing
do_no()  unless $x > 0;

עם אופרטורים לוגיים מקצרים#

?: מתקשר עם &&, ||, // בדרכים שעלולות לבלבל את העין. כמעט תמיד הקיפו בסוגריים:

my $x = $a || $b ? $c : $d;              # parses as ($a || $b) ? $c : $d
                                         # because || binds tighter than ?:
my $x = $a || ($b ? $c : $d);            # if you meant the other thing,
                                         # parenthesise

קדימות#

?: יושב בשורה 18 - רופף יותר מהאופרטורים הבוליאניים (&&/||///), הדוק יותר מהשמה. זו הסיבה ש־my $x = COND ? A : B עובד ללא סוגריים סביב הצד הימני.

ראו גם#