caller#
מחזיר מידע על תת־השגרה, eval, או require שקראו לקוד המבוצע כעת.
caller סורק את מחסנית הקריאות. ללא ארגומנט הוא מחזיר רשומה קצרה בת שלושה אלמנטים המזהה מי קרא לנו. עם ארגומנט מספרי EXPR הוא סורק EXPR מסגרות נוספות אחורה ומחזיר רשומה ארוכה יותר בת אחד־עשר אלמנטים - הצורה שבה משתמשים המנפה, מודולי stack-trace, ומנגנון warn/die כדי לקשט אבחונים בהקשר קובץ־ושורה. מסגרות XS אינן נראות ל־caller; מסגרת ה־pure-Perl הבאה צפה במקומן.
תקציר#
caller
caller EXPR
מה מקבלים בחזרה#
בהקשר סקלרי, שם החבילה של הקורא, או undef אם אין קורא (כלומר, אנו ברמה העליונה של הקובץ, לא בתוך sub, eval, או require):
my $pkg = caller;
בהקשר רשימה ללא ארגומנט, שלושה אלמנטים - החבילה, הקובץ ומספר השורה של הקורא הישיר:
# 0 1 2
my ($package, $filename, $line) = caller;
בהקשר רשימה עם ארגומנט מספרי, אחד־עשר אלמנטים המתארים את המסגרת EXPR רמות מעלה. 0 הוא הקורא הישיר, 1 הוא הקורא שלו, וכן הלאה:
# 0 1 2 3 4
my ($package, $filename, $line, $subroutine, $hasargs,
# 5 6 7 8 9 10
$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
= caller($i);
אחד־עשר השדות, לפי הסדר:
$package,$filename,$line- מיקום אתר הקריאה בתוך הקורא של אותה מסגרת. אותם שלושה ערכים שהצורה הקצרה מחזירה.$subroutine- שם מלא של תת־השגרה שאליה שייכת המסגרת, למשל"Foo::bar". עבור מסגרתevalזוהי המחרוזת המילולית"(eval)". אם תת־השגרה הוסרה מטבלת הסמלים מאז הקריאה, הערך הוא"(unknown)".$hasargs- אמת אם הוקצה@_חדש עבור המסגרת. שקר עבור מסגרותevalו־require.$wantarray- ההקשר שבו נקראה המסגרת, כפי ש־wantarrayהיה מדווח עליו: אמת עבור רשימה, מוגדר־אך־שקר ("") עבור סקלר,undefעבור void.$evaltext- עבור מסגרתeval EXPR, טקסט המקור שהודר. לא־מוגדר עבורeval BLOCKועבור מסגרות שאינןeval.$is_require- אמת אם המסגרת נוצרה על־ידיrequireאוuse(כלuseיוצר מסגרתrequireהמקוננת בתוך מסגרתeval EXPR).$hints- הערך של$^Hבנקודה שבה הודר קוד המסגרת. פנימי; המבנה אינו יציב בין גרסאות Perl.$bitmask- הערך של${^WARNING_BITS}באותה נקודה. גם זה פנימי.$hinthash- הפניה ל־האש%^Hשנלכדה בזמן ההידור, אוundefאם היא הייתה ריקה. אל תשנו אותה - ההפניה מצביעה ל־optree החי.
מצב גלובלי שהוא נוגע בו#
@DB::args- נקבע כתופעת לוואי כאשרcallerנקרא עם ארגומנט מתוך החבילהDB. רשימת הארגומנטים של הקורא מקושרת כ־alias למערך זה לצורך שימוש המנפה. ראו מקרי קצה למטה - זוהי השתדלות מיטבית עם פינות חדות.$^H,${^WARNING_BITS},%^H- נקראים מהמצב המהודר של מסגרת היעד כדי לאכלס את$hints,$bitmask,$hinthash.
דוגמאות#
למצוא את החבילה של הקורא הישיר ולדווח ליומן הנכון:
sub log_for_caller {
my $pkg = caller;
warn "[$pkg] @_\n";
}
להפיק תג מיקום בסגנון warn. caller מחזיר את שם הקובץ והשורה של אתר הקריאה מסגרת אחת למעלה, וזה כמעט תמיד המידע שבאמת רוצים באבחון:
sub note {
my (undef, $file, $line) = caller;
print STDERR "note at $file line $line: @_\n";
}
לסרוק את המחסנית המלאה. לבצע איטרציה על caller($i) עד שהוא מחזיר רשימה ריקה:
sub stacktrace {
my @frames;
for (my $i = 0; my @f = caller($i); $i++) {
push @frames, \@f;
}
return @frames;
}
לזהות האם תת־השגרה הנוכחית נקראה בהקשר רשימה, סקלרי, או void. זהו wantarray ברמה הנוכחית, אבל עבור מסגרת של מישהו אחר ניגשים אליה דרך caller:
sub describe_parent_context {
my $wa = (caller(1))[5];
return !defined $wa ? "void"
: $wa ? "list"
: "scalar";
}
להבחין בין מסגרת require/use לבין eval רגיל:
sub called_from_require {
my @f = caller(1);
return @f && $f[7]; # field 7 is $is_require
}
להציג מסגרת בודדת בדרך שבה הפורמטר ברירת המחדל של die / Carp עושה זאת - "at FILE line LINE":
sub location_tag {
my $depth = shift // 0;
my (undef, $file, $line) = caller($depth);
return defined $file ? "at $file line $line" : "at top level";
}
מקרי קצה#
הקשר סקלרי, אין קורא: ברמה העליונה של סקריפט,
scalar callerמחזירundef, ו־callerבהקשר רשימה מחזיר רשימה ריקה. ניב נפוץ עבור ״האם אני נטען כמודול על־ידיrequire, או רץ כסקריפט?״ הואcaller() ? ... : ....מסגרות XS מדולגות.
callerמדווח רק על מסגרות pure-Perl. אם תת־שגרת pure-Perl הופעלה על־ידי תת־שגרת XS שהופעלה על־ידי תת־שגרת pure-Perl אחרת,caller(0)מתת־השגרה הפנימית מדווח על תת־השגרת pure-Perl החיצונית - שכבת ה־XS אינה נראית. עומקי מחסנית הנמדדים עםcallerאינם כוללים אפוא את מעטפות ה־XS.למסגרות
evalאין ארגומנטים.$hasargsהוא שקר עבור מסגרותevalו־require, ו־$subroutineהוא המחרוזת המילולית"(eval)"- לא החבילה של הקוד הסובב.eval BLOCKמולeval EXPR. שניהם נותנים$subroutine eq "(eval)". רקeval EXPRממלא את$evaltext;eval BLOCKמשאיר אותוundef.useיוצר שתי מסגרות. הצהרתuse Fooמהודרת כ־BEGIN { require Foo; Foo->import; }, ו־requireעצמו מיושם כ־eval EXPR. סריקת המחסנית דרך שורתuseרואה אפוא מסגרתevalמסומנת ב־requireבתוך מסגרתevalרגילה. בדקו את$is_requireכדי להבחין.תת־שגרות
(unknown). אם תת־השגרה הנקובה במסגרת נמחקה מטבלת הסמלים (ניתוח טבלת־סמלים,delete $Foo::{bar}) בין הקריאה לבין ה־caller,$subroutineנקרא"(unknown)".לולאות ובלוקי
tryאינם מסגרות.while,for,foreach, ו־tryאינם יוצרים מסגרות קריאה.callerרואה רק קריאות לתת־שגרות ו־evalים.מסגרות שהושמטו על־ידי המייעל. המייעל עשוי להסיר tail-call ומסגרות דומות לפני ש־
callerיכול לצפות בהן. עבורcaller(N)עםN > 1, המסגרת שמתקבלת אינה מובטחת להיות המסגרת שציפיתם לה. אין לקודד את עומק המחסנית כחוזה נושא־עומס.@DB::argsהוא השתדלות מיטבית. הוא מאוכלס רק כאשרcallerנקרא עם ארגומנט מתוך החבילהDB. הערכים הם aliases לתוך@_של מסגרת היעד, לא עותקים - ולכן:שינויים שהמסגרת כבר ביצעה ב־
@_נראים; הערכים המקוריים מזמן הקריאה אינם נשמרים.shift @_בתוך המסגרת מבוטל בדרך כלל ב־@DB::args, אבלpop @_, splices, או לקיחת הפניה ל־@_כולם שוברים זאת.אלמנטים עשויים להיות משוחררים ומשומשים מחדש עבור ערכים אחרים עד הזמן שתקראו אותם.
מצב מיושן מקריאת
callerקודמת עשוי עדיין להיות ב־@DB::argsאם הקריאה הנוכחית לא הפעילה רענון. השתמשו בו ל־backtraces ולתצוגת מנפה; אל תסתמכו עליו ללוגיקת התוכנית.
$hinthashחי. הפניית ההאש בשדה 10 מצביעה לתמונת ה־%^Hבפועל המוטמעת ב־optree. שינוי תוכנו משנה את מצב המהדר. קראו אותו; אל תכתבו אליו.שם קובץ ושורה ניתנים לשכתוב. הוראות
#lineוכל דבר אחר שמנגנון ה־“Plain Old Comments (Not!)“ מזהה (ראוperlsyn) משנים את הערכים ש־callerמדווח, בדיוק כפי שהם משנים את__FILE__ו־__LINE__.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
die- מעלה חריגה; הודעת ברירת המחדל שלו משתמשת באותו מידע קובץ־ושורה ש־callerחושףeval- יוצר מסגרות ש־callerמסמן עם$subroutine eq "(eval)"ועשוי למלא$evaltext/$is_requirewantarray- מדווח על הקשר הקריאה של המסגרת הנוכחית; אותו ערך מופיע כשדה 5 שלcaller(N)עבור המסגרתNרמות מעלה$^H- ביטי רמז של זמן ההידור; מוצגים כשדה 8%^H- האש רמזים של זמן ההידור; מוצגת כשדה 10${^WARNING_BITS}- מסכת ביטים של אזהרות; מוצגת כשדה 9