טיפול בחריגות
הוצג| English | משמעות |
|---|---|
| exception/ekˈsepʃn/ | חריגה |
| exception handling/ekˈsepʃn ˈhændlɪŋ/ | טיפול ביוצאי דופן |
| raise/reɪz/ | השקת (Exception) |
הבדיקה שאין לכתוב אותה
- תוכנית פותחת קובץ. לפני הפתיחה ניתן לבדוק אם הקובץ קיים, אם הוא נגיש לקריאה, אם הדיסק מחובר. נניח שכל הבדיקות עברו בהצלחה.
- בין הבדיקה האחרונה לפתיחה, המשתמש מוציא את סטיק ה-USB. הקובץ היה קיים כששאלת, ואינו קיים כשפותחת אותו, ואף בדיקה מראש לא יכולה הייתה לגשר על הפער הזה.
- חלק מהשגיאות פשוט אינן ניתנות למניעה, כי העולם משתנה בין הבדיקה לפעולה. מה שתוכנית יכולה לעשות הוא להגיב אליהן כשהן מתרחשות.
- שיעור זה הוא היציאה ממבנה ה-TRY המטפל בחריגה אחת, וקובע היכן בתוכנית יש לתפוס חריגה.
מהי חריגה ולמה לטפל בה
- חריגה היא שגיאה המתרחשת בזמן ביצוע: חלוקה באפס, קובץ לא נמצא, כניסה לא חוקית, רשת שהתנתקה.
- טיפול בחריגות מאפשר לתוכנית לזהות את השגיאה ולהגיב עליה בצורה מסודרת, במקום לקרוס ולהפסיד את העבודה של המשתמש.
- תוכניות אמיתיות מתמודדות עם שגיאות שלא ניתן למנוע מראש, כפי שמראה הקישוט. וללא חריגות, כל פעולה בנפרד הייתה זקוקה לבדיקת
IFמשלה, והאלגוריתם האמיתי היה נטמון בבדיקות שגיאה. - היתרון השלישי הוא זה שרוב שואלים במבחן: הוא מפריד בין הזרימה הרגילה לטיפול בשגיאות, כך שהדרך הראשית נשארת ברורה.
שגיאת חריגה היא:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
חריגות הן בעיות בזמן הרצה (חילוק באפס, קובץ לא נמצא) שמטפלים בהן מאפשרים תגובה מסודרת.
מדוע להשתמש במניעת חריגות במקום לבדוק כל שגיאה מראש? סמן את כולם האפשרויות הנכונות.
Difficulty 2/5 · 140 coins + a small bonus on first completion today
היתרונות הם דיוק והבהירות. המהירות אינה אחת מהם; הטופל המוסף מעט עומס, שהוא שווה בתשלום.
מבנה ה-TRY
TRY
OPENFILE "data.txt" FOR READ
READFILE "data.txt", line
CLOSEFILE "data.txt"
EXCEPT FileNotFound
OUTPUT "Sorry, the file does not exist."
EXCEPT ReadError
OUTPUT "Sorry, there was an error reading the file."
FINALLY
OUTPUT "Finished attempting to read."
ENDTRY
- בלוק ה-TRY מכיל את הקוד שעלול להכשל. אם הוא מתבצע ללא שגיאה, בלוקי ה-EXCEPT דווקא מועברים.
- אם מתרחשת חריגה, הביצוע עובר מיד לבלוק EXCEPT התואם הראשון. שאר חלקי בלוק ה-TRY אינם מתבצעים.
- בלוק FINALLY מתבצע בכל מקרה, בין אם התרחשה חריגה או לא, מה שהוא הופך אותו למקום הנכון לניקוי כמו סגירת קובץ.

מסלול אחד כאשר הכל בסדר, מסלול אחר כאשר יש בעיה, ומסלול שנשמע תמיד
כיצד זרימת טיפול בחריגות מתנהלת
עבור שלב-בשלב על מה שקורה כשהקוד נכשל. החריגה קופצת מחוץ לזרימה הרגילה למטפל, FINALLY מבצע ניקוי בכל מקרה, והתוכנית ממשיכה במקום להתמוטט.
התאם כל מילת מפתח לטיפול בחריגות למשימה שלה.
Difficulty 2/5 · 140 coins + a small bonus on first completion today
TRY מגן על הקוד הסיכון, EXCEPT תופס, FINALLY מנקה בכל אופן, RAISE זורק שגיאה שתופסו.
בלוק FINALLY:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
FINALLY תמיד מתבצע, מה שהופך אותו לאידיאלי לניקוי כמו סגירת קבצים.
הבלוק שמתבצע בין אם התרחשה חריגה ובין אם לא, מה שהוא מתאים לסגירת קבצים, הוא ____.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
הניקוי חייב לקרות בשני המסלולים. השמת CLOSEFILE רק בבלוק TRY פירושה שהוא יודלג בדיוק כששגיאה עזבה את הקובץ פתוח.
דוגמה פותרת: מעקב אחר הזרימה
- בתוכן לעיל, הקובץ אינו קיים. ציין בדיוק מה יוצא והמה מועבר.
OPENFILEגורם לFileNotFound, ולכן הביצוע עוזב את בלוק ה-TRY במייד: ה-READFILEוה-CLOSEFILEלעולם לא יתבצעו.- בלוק ה-
FileNotFoundEXCEPT מתבצע, ומדפי "Sorry, the file does not exist." בלוק ה-ReadErrorלא מתבצע, כי רק הטייפול התואם הראשון משמש. - בלוק ה-FINALLY מתבצע, ומדפי "Finished attempting to read."
- הנקודה שמפסידים עליה הכי הרבה היא הבנה שכותרת ה-TRY הנותרת נזרקת.
הקובץ בבלוק TRY אינו קיים. סדר מה שקורה.
Difficulty 3/5 · 200 coins + a small bonus on first completion today
רק המטפל הראשון המתאים מתבצע, ו-FINALLY מתבצע בכל אופן. השארית המודלעת של בלוק TRY היא הסמן שמחמיצה הכי הרבה פעמים.
הרמת חריגה
- פונקציה שזיהתה בעיה she cannot sensibly deal with can raise an exception, passing responsibility to whoever called it:
IF b = 0 THEN RAISE DivideByZero
- זהו העיצוב הנכון כאשר התת-תוכנית יודעת שיש בעיה, אך לא מה יש לעשות לגביה. רoutine חלוקה יודעת שהמחלק הוא אפס; רק הקורא יודע אם לבקש מהמשתמש שוב, להשתמש בערך ברירת מחדל או לוותר על החישוב.
תת-תוכנית משתמשת ב-RAISE כדי:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
RAISE מזרקת חריגה כלפי מעלה לקורא, שיכול לתפוס אותה עם EXCEPT.
מדוע תת-תוכנית חלוקה RAISE חריגה במקום לטפל בעצמה במחלק אפס?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
לבקש מהמשתמש שוב, להשתמש בערך ברירת מחדל, או לוותר על החישוב: רק הקוד המקרא הוא שמחזיק את ההקשר לבחירה.
איפה לטפל בזה
- טפל בחריגה קרוב למקום שבו היא מתרחשת כאשר התגובה פשוטה ומקומית: הדפס הודעה, השתמש בערך ברירת מחדל, בקש מהמשתמש לנסות שוב.
- טפל בה גבוה יותר כאשר ההחלטה שייכת לחלק גדול יותר בתוכנה: האם לוותר על עסקה שלמה, לבטל שינוי או להודיע למשתמש שהפעולה נכשלה.
- הכלל הפשוט: תפוס אותה ברמה שיש לה מספיק מידע כדי לקבוע מה לעשות, ולא ברמה שראשונה שמתעצבת ממנה.
דוגמה פתורה: מה לא לעשות
- תלמיד כותב
EXCEPT: (do nothing)סביב תוכנית שלמה כך she never crashes. הסבר מדוע זו תרגול גרוע. - החריגה נבלעת: התוכנית ממשיכה כאילו לא קרה כלום, ולכן היא ממשיכה עם נתונים חסרים או לא תקינים ומייצרת תוצאות שגויות במקום כשל מיידי.
- כשל שקט קשה לאבחן מכשל קריסה, כי אין הודעה ואין indication של איפה זה קרה.
- תפיסת כל החריגות במקום אחד גם אומרת שהסוג הספציפי של השגיאה מאבד, ולכן אין אפשרות לבחור תגובה הגיונית. המטפל צריך לתפוס חריגה ספציפית ולמעשה להגיב אליה.
בליעה שקטה של חריגה (לכידתה אך ביצוע פעולה כלשהי) מסתרת טעויות אמיתיות ומקשה על בדיקת באגים — יש לטפל בהן או לפחות להקליט אותן.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
מטפל ריק מסתיר את הבעיות שאתה צריך למצוא; יש להגיב תמיד או להקליט את השגיאה.
סימונים נופלים מהיד
- כאשר חריגה מתרחשת, שאר בלוק ה-TRY מוותר. אמור זאת בזמן מעקב.
- רק ה-EXCEPT הראשון המתאים רץ, לא כולם.
- FINALLY תמיד רץ, עם טעות או בלי, וזה מה שמפנה אותו לניקוי קבצים.
- אל תפוס חריגה ועשה כלום. שגיאה שנבלעת גרועה מכשל, כי התוכנית ממשיכה עם נתונים רעים.
הבנתך מושלמת
- חריגה היא שגיאת ריצה; טיפול בה מאפשר לתוכנית להגיב במקום להתמוטט, מכסה שגיאות שאין למנוע מראש, ומפריד קוד רגיל מטיפול בשגיאות.
- TRY מחזיק את הקוד הסיכון; בטעות שאחריו מוותר וה-EXCEPT הראשון המתאים רץ; FINALLY רץ בכל מקרה, ולכן ניקוי שייך לשם.
- תת-תוכנית שלא יכולה לקבוע את התגובה צריכה לזרוק (RAISE) את החריגה לקורא שלה.
- טפל בה קרוב לתגובה מקומית פשוטה, גבוה יותר כאשר ההחלצה זקוקה לתמונה רחבה; לעולם אל תפוס ותעשה כלום.