זרימת בקרה

continue#

מצרף לולאה לבלוק שרץ לאחר כל איטרציה, רגע לפני שהתנאי נבדק שוב.

continue אינה פונקציה מובנית - זוהי מילת מפתח של זרימת בקרה. במשמעותה היחידה שנותרה היא מציגה את הבלוק הגורר של לולאת while, until, או foreach. הבלוק רץ בסוף כל איטרציה וגם בכל פעם ש־next מעביר בקרה החוצה מהגוף הראשי, אבל לא כאשר last או redo עושים זאת. הוא משחק את התפקיד שהפסוקית השלישית של לולאת for (init; cond; step) ב־C משחקת ב־C.

תקציר#

while (EXPR) { BODY } continue { STEP }
until (EXPR) { BODY } continue { STEP }
for VAR (LIST) { BODY } continue { STEP }
foreach VAR (LIST) { BODY } continue { STEP }
LABEL: while (EXPR) { BODY } continue { STEP }

מה מקבלים בחזרה#

continue היא הוראה, לא ביטוי. אין לה ערך החזרה והיא לא יכולה להופיע במיקום של ערך. הלולאה עצמה מניבה את מה שההקשר שלה דורש (כלום בהקשר void, הביטוי האחרון שהוערך תחת חלק מהמבנים); בלוק ה־continue אינו תורם לכך.

מודל הביצוע#

עבור לולאה עם בלוק continue מצורף, כל איטרציה רצה בסדר הזה:

  1. הערכת התנאי (או לקיחת אלמנט הרשימה הבא, עבור foreach). אם הלולאה לא צריכה לרוץ שוב, יציאה.

  2. הרצת הגוף הראשי.

  3. הרצת בלוק ה־continue.

  4. חזרה לשלב 1.

שלוש מילות המפתח של בקרת הלולאה מתאימות עם בלוק ה־continue באופן שונה:

  • next - קופץ ישר לשלב 3. בלוק ה־continue מורץ, אחר־כך התנאי נבדק שוב. זוהי כל הנקודה של בלוק continue: מצב שחייב להתקדם בכל איטרציה (מונה, מספר שורה, איפוס התאמה חד־פעמית) עדיין מתקדם כשהגוף מקצר באמצעות next.

  • last - יוצא מהלולאה כליל. בלוק ה־continue אינו מורץ.

  • redo - מתחיל את שלב 2 מחדש מבלי לבדוק שוב את התנאי ומבלי להריץ את בלוק ה־continue. יש להשתמש בו כאשר הגוף זקוק למעבר נוסף על נתוני האיטרציה הנוכחית (לדוגמה, לאחר שילוב של קלט נוסף).

השמטת בלוק ה־continue שקולה לבלוק ריק.

דוגמאות#

מונה שמתקדם גם כשהגוף מדלג:

my $n = 0;
for my $line (@lines) {
    next if $line =~ /^\s*#/;    # skip comments
    process($line);
} continue {
    $n++;                        # still counts skipped lines
}
print "scanned $n lines\n";

שקילות ללולאת for בסגנון C - שתי הצורות למטה זהות, כי Perl כותב מחדש את הכותרת בסגנון C כ־while עם בלוק continue:

for (my $i = 1; $i < 10; $i++) { say $i }

my $i = 1;
while ($i < 10) {
    say $i;
} continue {
    $i++;
}

איפוס התאמות חד־פעמיות ומוני שורות בעת זרימת קבצים עם <>:

while (<>) {
    m?(fred)?   && s//WILMA/;
    m?(barney)? && s//BETTY/;
} continue {
    print "$ARGV $.: $_";
    close ARGV if eof;           # reset $.
    reset      if eof;           # reset ?pat?
}

האינטראקציה עם redo - שימו לב ש־continue רץ במסלול של next אבל לא במסלול של redo:

while (<>) {
    chomp;
    if (s/\\$//) {
        $_ .= <>;
        redo unless eof;         # merge continuation, re-enter body
    }                            # continue block skipped on redo
    process($_);
} continue {
    $seen++;                     # counts completed records only
}

מקרי קצה#

  • ללא בלוק גורר - continue חשוף (ללא { ... } עוקב) הוא שגיאת ניתוח ב־Perl 5.42. הוא היה הוראה תקפה בתוך המבנה given / when של תכונת switch, שם נפל למקרה ה־when הבא. תכונה זו הוסרה ב־5.42; ל־continue יש משמעות עתה רק כבלוק גורר של לולאה.

  • last מדלג על בלוק ה־continue. אם הבלוק מחזיק ניקוי שאתם צריכים בכל מסלול יציאה, יש להניח את הניקוי לאחר הלולאה או ב־scope guard, לא ב־continue.

  • redo מדלג על בלוק ה־continue. אם בלוק ה־continue מקדם מונה, איטרציית redo לא תקדם אותו - זה לרוב מה שרוצים (האיטרציה עדיין לא הסתיימה) אבל זה יכול להפתיע קוד הסומך על כך שהמונה תואם את מספר הכניסות לגוף.

  • do { ... } while אינה לולאה אמיתית - last, next, ו־redo לא עובדים בה, ובלוק continue גורר הוא שגיאת תחביר.

  • לולאות עם תווית - LABEL: מצורף למילת המפתח while / for / foreach, לא ל־continue. next LABEL ו־last LABEL מכוונים ללולאה כולה; בלוק ה־continue הוא חלק מאותה לולאה.

  • בלוק לבדו הוא לולאה חד־פעמית, אז { ... } continue { ... } חשוף מנותח ומריץ את בלוק ה־continue פעם אחת לאחר הגוף - שימושי לעיתים נדירות, אך חוקי.

  • Foreach עם aliasing - בתוך לולאת foreach משתנה הלולאה מהווה alias לאלמנט הרשימה הנוכחי. בלוק ה־continue עדיין רץ עם alias זה בתחום, ולכן ניתן לבחון או לשנות את האלמנט שם בדיוק כמו בגוף.

הבדלים מ־upstream#

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

ראו גם#

  • next - קופץ לבלוק ה־continue (אם קיים) ובודק שוב את התנאי; מילת המפתח היחידה של בקרת לולאה שכן מריצה את בלוק ה־continue

  • last - יוצא מהלולאה כליל; מדלג על בלוק ה־continue

  • redo - מתחיל את הגוף מחדש מבלי לבדוק שוב את התנאי; מדלג על בלוק ה־continue

  • return - יוצא מתת־השגרה העוטפת; גם הוא מדלג על בלוק ה־continue כי הוא יוצא מהלולאה

  • break - מילת מפתח נלווית של תכונת ה־switch שהוסרה; כמו צורת given / when החשופה של continue, אינה זמינה עוד ב־5.42