זרימת בקרה

break#

יציאה מבלוק given.

break מסיים מיד את בלוק given העוטף ומעביר את הבקרה להוראה שלאחריו - האנלוג של given למה ש־last עושה ללולאות. הוא אינו מקבל ארגומנטים, אינו מחזיר ערך, וחל רק על ה־given הפנימי ביותר; הוא אינו יכול לכוון לבלוק חיצוני באמצעות תווית.

תקציר#

break

זמינות - קראו זאת תחילה#

break היא מילת מפתח של התכונה switch, יחד עם given, when, default, ו־(בתוך when) continue. ב־Perl 5.42 תכונת ה־switch מושבתת כברירת מחדל ואינה חלק מאף חבילת תכונות נוכחית: use v5.36 עד use v5.42 אינם מפעילים אותה. התכונה עדיין קיימת וניתן להשתמש בה, אך רק תחת הפעלה מפורשת:

use feature 'switch';
no warnings 'experimental::smartmatch';

ללא הפעלה זו, ה־bareword break מתפרסר כקריאת תת־שגרה רגילה ונכשל בזמן ההידור עם Bareword "break" not allowed while "strict subs" in use, או בזמן ריצה עם Undefined subroutine &main::break called. הצורה המוסמכת במלואה CORE::break פועלת מכל תחום מבלי להפעיל את התכונה, וזו הדרך להפעיל אותה בקוד שאחרת שומר על switch מושבת.

given/when מסתמכים על smartmatch (~~), שהוא עצמו ניסיוני ומפיק אזהרה בכל שימוש אלא אם אזהרות experimental::smartmatch מושתקות. קוד חדש לא צריך להישען על given/when/break; ראו תחליפים למטה.

התנהגות#

בתוך בלוק given, break משחרר עד להוראה שמיד אחרי הבלוק. הוא שקול למה שנופל מתחתית ענף when באופן מובלע - סעיפי when מבצעים break בסוף גופם אלא אם הגוף מסתיים ב־continue, כך ש־break מפורש משמש בעיקר ליציאה מוקדמת מגוף when ארוך:

use feature 'switch';
no warnings 'experimental::smartmatch';

given ($cmd) {
    when ('quit') {
        cleanup();
        break if $fast_exit;        # skip the logging below
        log_exit();
    }
    when ('help') { show_help() }
    default       { warn "unknown: $cmd" }
}

מחוץ לבלוק given, break מעלה Can't "break" outside a given block בזמן ריצה.

תחליפים#

לקוד חדש, העדיפו את אחת מהצורות הבאות. הן Perl רגיל, אינן דורשות הפעלת תכונה, ואין מעליהן ענן של הוצאה משימוש:

  • שרשרת if / elsif / else - תחליף ישיר לרוב השימושים של given/when:

    if    ($cmd eq 'quit') { cleanup(); log_exit() }
    elsif ($cmd eq 'help') { show_help() }
    else                   { warn "unknown: $cmd" }
    
  • טבלת dispatch - האש של coderef־ים ממופתחים לפי הקלט, עם ענף ברירת מחדל. מתאפיינת בקנה־מידה טוב יותר מסולם elsif ארוך והופכת את אוסף המקרים המטופלים לנתונים במקום לזרימת בקרה:

    my %dispatch = (
        quit => sub { cleanup(); log_exit() },
        help => \&show_help,
    );
    ($dispatch{$cmd} // sub { warn "unknown: $cmd" })->();
    
  • לולאה מתויגת עם last - כאשר רוצים ספציפית את צורת ״יציאה מוקדמת מבלוק זה״ ש־break סיפק, עטפו את הגוף בבלוק חשוף ובצעו last ממנו:

    CMD: {
        if ($cmd eq 'quit') { cleanup(); last CMD if $fast_exit; log_exit(); last CMD }
        if ($cmd eq 'help') { show_help(); last CMD }
        warn "unknown: $cmd";
    }
    

דוגמאות#

הפעלת תכונה מפורשת, יציאה מוקדמת מגוף when:

use feature 'switch';
no warnings 'experimental::smartmatch';

given ($n) {
    when ($_ < 0) { warn "negative"; break }   # skip the log below
    when (0)      { warn "zero" }
    default       { warn "positive: $n" }
}
# control resumes here after break

שימוש ב־CORE::break מבלי להפעיל את התכונה גלובלית:

sub classify {
    my ($n) = @_;
    given ($n) {
        when ($_ < 0) { return "neg"; CORE::break }
        when (0)      { return "zero" }
        default       { return "pos" }
    }
}

מקרי קצה#

  • ללא צורת ארגומנט. break אינו מקבל דבר. break LABEL היא שגיאת תחביר - בניגוד ל־last/next, ל־break אין דרך לכוון לבלוק חיצוני.

  • מחוץ ל־given. קריאה ל־break (או CORE::break) כאשר אין בלוק given במחסנית הקריאות מעלה Can't "break" outside a given block.

  • return מנצח. בתוך תת־שגרה, return משחרר את כל התת־שגרה ללא תלות בכל given עוטף. break משחרר רק עד סוף ה־given; הבקרה ממשיכה בתת־השגרה הסובבת.

  • break מובלע בסוף when. גוף של סעיף when מסתיים ב־break מובלע אלא אם הגוף הוא continue, כך ש־break מפורש בסוף גוף when הוא יתיר. continue מדכא את ה־break המובלע ומאפשר לבקרה ליפול לתוך ה־when הבא.

  • לא מילת מפתח של לולאה. break אינו מתממשק עם for, while, foreach, do, או בלוקים חשופים. עבור אלה, השתמשו ב־last.

  • אזהרות ניסיוניות. הרצת קוד given/when ללא no warnings 'experimental::smartmatch' מדפיסה את האזהרה פעם אחת לכל אתר smartmatch, מה שבבלוק given עמוס יכול להיות כל איטרציה.

הבדלים מ־upstream#

תואם מלא ל־upstream Perl 5.42.

ראו גם#

  • last - מקבילת הלולאה; יוצא מ־for / while / foreach / בלוק חשוף הפנימי ביותר העוטף, ובניגוד ל־break יכול לכוון לבלוק חיצוני באמצעות תווית

  • next - התחלת האיטרציה הבאה של לולאה במקום יציאה ממנה; שימושי כאשר break הוא הצורה הלא־נכונה משום שרוצים המשכיות, לא סיום

  • return - משחרר אל מחוץ לתת־השגרה העוטפת לחלוטין, ולא רק את בלוק ה־given; השתמשו כאשר ה־given הוא dispatcher בתוך תת־שגרה והתשובה מוכנה