warn#
מנפיק אזהרה ל־STDERR.
warn הופך את LIST למחרוזת ומדפיס את התוצאה ל־STDERR - אותו מנגנון עיצוב כמו die, פחות השחרור. הבקרה חוזרת לקורא; דבר אינו נזרק, דבר אינו נתפס. יש לפנות אליו כאשר התוכנית צריכה להמשיך לרוץ אבל המשתמש, המפעיל, או הלוג ראויים לשמוע על משהו לא צפוי.
תקציר#
warn LIST
warn $message
warn # re-surface current $@ as a warning
מה מקבלים בחזרה#
warn מחזיר 1 בנסיבות רגילות. ערך ההחזרה כמעט אף פעם אינו שימושי - נקודת הקריאה היא תופעת הלוואי על STDERR (או על מה ש־$SIG{__WARN__} עושה עם ההודעה).
שלא כמו die, warn אינו משחרר. הביצוע ממשיך עם המשפט אחרי הקריאה.
מצב גלובלי שהוא נוגע בו#
$@- נקרא על ידי הצורה ללא ארגומנט. אם$@מחזיק ערך לא־ריק,warnמחזיר אותו לפני השטח (ראו התפשטות להלן).warnאינו כותב את$@.$,,$\- אינם נועצים.warnאינוprint; מפרידי הפלט ומפריד הרשומות אינם משחקים תפקיד. ההודעה נכתבת כמחרוזת יחידה.$.- מספר השורה הנוכחית של הקלט, מצורף להודעות שחסרה להן שורה חדשה גוררת.$SIG{__WARN__}- אם מוגדר, המטפל רץ במקום כתיבה ל־STDERR. ראו הוו של$SIG{__WARN__}להלן.STDERR- היעד בברירת מחדל. כל הפניה מחדש שלSTDERR(2>ברמת shell,open STDERR, ..., שכבת PerlIO) משפיעה על איפה פלטwarnנוחת.
חוק השורה החדשה הגוררת#
אותו כלל כמו die חל, ומאותה סיבה:
ההודעה מסתיימת ב־
"\n"- בשימוש מילולית. דבר אינו מצורף. יש להשתמש בזה לאזהרות שהן אבחנות שלמות הפונות למשתמש.ההודעה אינה מסתיימת ב־
"\n"- Perl מצרף" at FILE line N", ואם קובץ נקרא,", <HANDLE> line M", ואז"."סופי ושורה חדשה. יש להשתמש בזה כשציון מדויק של אתר הקריאה שימושי יותר מהודעה מסודרת.
warn "cache is stale\n"; # "cache is stale\n"
warn "cache is stale"; # "cache is stale at main.pl line 42.\n"
אזהרות בערך הפניה לעולם אינן מקבלות מידע מיקום מצורף. הפיכת עצם למחרוזת כדי להוסיף קובץ ושורה תסכל את הנקודה של העברתו.
התפשטות: warn ללא ארגומנט (או מחרוזת ריקה)#
כאשר LIST ריק או הופך למחרוזת "", warn אינו מנפיק הודעה רעננה - הוא מחזיר לפני השטח את מה שיש ב־$@:
אם
$@לא־ריק,warnמצרף לו"\t...caught"ומנפיק את התוצאה. זוהי הדרך הקנונית להבחין שחריגה נתפסה מבלי לאפשר לה למות בשקט:eval { risky() }; warn if $@; # "<whatever died>\n\t...caught at ..."
אם
$@גם ריק, המחרוזת"Warning: Something's wrong"בשימוש.
זה חוסר סימטריה בכוונה עם die: die ללא ארגומנט זורק מחדש (מפעיל את מנגנון ההתפשטות ואת הוו PROPAGATE עבור עצמים); warn ללא ארגומנט מדווח על מה שכבר ב־$@.
הוו $SIG{__WARN__}#
הגדרת $SIG{__WARN__} מתקינה מטפל הרץ במקום הכתיבה לברירת מחדל ל־STDERR. המטפל מקבל את החריגה הנגזרת מ־LIST כארגומנט יחיד והוא אחראי לסילוקה - רישומה ב־log, כתיבה מחדש שלה, הסלמה שלה ל־die, או הפלתה לרצפה:
local $SIG{__WARN__} = sub {
my ($msg) = @_;
return if $msg =~ /^Use of uninitialized/; # silently drop
log_warning($msg);
};
שלוש חוסרי־סימטריה עם $SIG{__DIE__} שכדאי להפנים:
ההודעה בברירת מחדל מדוכאת.
$SIG{__DIE__}רץ לצד מנגנון החריגה;$SIG{__WARN__}רץ במקום הכתיבה ל־STDERRבברירת מחדל. אם המטפל לא עושה דבר, האזהרה מופלת בשקט.כדי להעביר את האזהרה דרך, יש לקרוא ל־
warnשוב. המטפל אינו נכנס מחדש לקריאתwarnשלו, כך שאין לולאה אינסופית:local $SIG{__WARN__} = sub { log_warning($_[0]); warn $_[0]; # re-emit to STDERR as well };
מטפל
__WARN__יכול להשתיק אזהרות חובה - אזהרות ש־no warningsאינו יכול לכבות. זה הופך את$SIG{__WARN__}לפטיש; עדיףno warnings '<category>'לדיכוי ממוקד ולשמור את המטפל לניתוב או הסלמה.
# wipe out *all* compile-time warnings, then switch on at runtime
BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } }
my $foo = 10;
my $foo = 20; # duplicate-my silenced
$DOWARN = 1;
warn "\$foo is alive and $foo"; # now shows up
warn המובנה מול use warnings#
אלה דברים שונים. אסור לבלבל ביניהם:
warnהיא פונקציה מובנית המנפיקה הודעה יחידה כעת. אתם קוראים לה.use warningsהוא pragma המאפשר קטגוריות של אבחנות זמן הידור וזמן ריצה (ערכים לא־מאותחלים, תכונות מיושנות, מטפלי קובץ לא־פתוחים, וכן הלאה). המהדר והמפרש מנפיקים את האבחנות הללו בעבורכם, באמצעות אותו מנגנון ש־warnמשתמש בו.
האבחנות של ה־pragma זורמות דרך $SIG{__WARN__} בדיוק כמו קריאות warn מפורשות. no warnings '<category>' מדכא את האבחנות של ה־pragma בתיחום הלקסיקלי שלו אך אין לו השפעה על warn מפורש שכתבתם בעצמכם - אותה קריאה תמיד נורה.
דוגמאות#
דיווח על בעיה הניתנת לשחזור והמשך:
open my $fh, "<", $path
or warn "skipping $path: $!\n" and next;
אבחנה במצב פיתוח עם מיקום מצורף:
warn "unexpected record shape";
# unexpected record shape at parser.pl line 87.
הבחנה בחריגה שנתפסה מבלי לדכא אותה:
eval { load_config() };
warn if $@; # surfaces "...caught at ..."
ניתוב כל אזהרה דרך logger, תוך המשך הדפסה ל־STDERR:
local $SIG{__WARN__} = sub {
my ($msg) = @_;
$logger->warn($msg);
print STDERR $msg; # preserve default visibility
};
הסלמת אזהרה מסוימת לשגיאה קטלנית:
local $SIG{__WARN__} = sub {
die @_ if $_[0] =~ /corrupt database/;
warn @_; # everything else: default path
};
העברת עצם bless לאזהרות מובנות (המקבל של הוו $SIG{__WARN__} מקבל את ההפניה, לא צורה הפוכה למחרוזת):
local $SIG{__WARN__} = sub {
my ($w) = @_;
if (ref($w) && $w->isa('MyApp::Warning')) {
$logger->record($w);
}
else {
print STDERR $w;
}
};
warn MyApp::Warning->new(code => 'SLOW_IO', detail => $path);
מקרי קצה#
רשימה עם שני איברים או יותר מופכת למחרוזת ומשורשרת:
warn "bad record ", $n, ": ", $raw. כלל השורה החדשה חל על התוצאה המשורשרת.רשימה ריקה (
warn;אוwarn "";) מפעילה את מסלול ההתפשטות, לא הודעה רעננה.אזהרה בערך הפניה בתוך מטפל
$SIG{__WARN__}: המטפל מקבל את ההפניה ללא שינוי. אם לא מותקן מטפל, ההפניה הופכת למחרוזת ל־STDERRדרך ה־overload של""שלה (או ברירת המחדל של PerlMyClass=HASH(0x...)).warnבתוך$SIG{__WARN__}: אינו נכנס מחדש למטפל. הקריאה כותבת ל־STDERRכאילו לא הותקן מטפל. זה מה שהופך את הניב ”העברה דרך“ לבטוח.warnבמהלך הריסה גלובלית: עדיין עובד, אךSTDERRעשוי כבר להיות סגור במקרים פתולוגיים. אזהרות ממטפליDESTROYהרצים ביציאת המפרש יכולות להיעלם.STDERRסגור או מופנה:warnכותב למה ש־STDERRמצביע אליו כעת. אםSTDERRסגור, הכתיבה נכשלת בשקט; שגיאה אינה מועלית, מכיוון ש־warnעצמו אינו בודק.אין קשר ל־
$\/$,: הוספתlocal $\ = "\n"אינה גורמת ל־warn "x"להדפיס שורה חדשה. כלל השורה החדשה הגוררת הוא המנגנון היחיד להוספת שורה חדשה עבורwarn.
הבדלים מהמקור#
תואם במלואו ל־Perl 5.42 במקור.
ראו גם#
die- אותם כללי עיצוב (שורה חדשה גוררת מדכאת מיקום, הפניות עוברות דרך ללא שינוי), אך מעלה חריגה במקום לדווח ולהמשיךeval- זווג עם הצורה ללא ארגומנט שלwarnעבור הניב ”תפיסה, בדיקה, החזרה לפני השטח“$@- המקור ש־warnללא ארגומנט מדווח ממנו$SIG{__WARN__}- הוו שמחליף את הכתיבה ב־STDERRבברירת מחדל; יש להשתמש בו לניתוב, סינון, או הסלמהCarp-carp,cluck,croak,confess: אזהרות וחריגות המדווחות מנקודת המבט של הקורא במקום מאתר הקריאה, וזה כמעט תמיד מה שספרייה רוצה