זרימת בקרה

FILE#

שם קובץ המקור שבו הטוקן מהודר.

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

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

תקציר#

__FILE__

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

מחרוזת: שם הקובץ כפי שהמהדר הכיר אותו כשקרא טוקן זה. עבור סקריפט שהופעל כ־perl /tmp/run.pl הערך הוא /tmp/run.pl; עבור מודול שנטען דרך require או use זהו הנתיב ש־require פתר מול @INC (בדרך כלל נתיב מוחלט). עבור קוד שמוזן בקלט הסטנדרטי או דרך -e הערך הוא - או -e בהתאמה.

מכיוון שההחלפה מתרחשת בזמן הידור, הערך קבוע לכל מופע טקסטואלי של הטוקן. שני טוקני __FILE__ בקבצים שונים מפיקים מחרוזות שונות; שניים באותו קובץ מפיקים את אותה מחרוזת.

מצב גלובלי שהוא נוגע בו#

ללא, בזמן ריצה. בזמן הידור הערך נלקח משם הקובץ הנוכחי של המהדר, שהוא אותו ערך ש־caller מדווח עליו בהקשר רשימה כאלמנט [1] ושבו die / warn משתמשים לבניית הסיומת ברירת המחדל שלהם "at FILE line LINE.".

שם הקובץ הזה יכול להיכתב מחדש על ידי הוראת #line המוטמעת במקור - ראו מקרי קצה להלן. לאחר הכתיבה מחדש, טוקני __FILE__ המהודרים לאחר ההוראה מדווחים את השם החדש.

דוגמאות#

זיהוי הסקריפט הרץ בשורת לוג:

warn "started from ", __FILE__, "\n";
# started from /tmp/run.pl

צירוף מיקום המקור לשגיאה מותאמת אישית ללא סיומת ברירת המחדל של die:

sub fail {
    my ($msg) = @_;
    die sprintf("%s at %s line %d\n", $msg, __FILE__, __LINE__);
}

בניית נתיב יחסי למודול הנוכחי, כדי שקובצי משאבים יישלחו לצד הקוד שטוען אותם:

use File::Basename qw(dirname);
use File::Spec;
my $data = File::Spec->catfile(dirname(__FILE__), "data.txt");

שימוש ב־__FILE__ בתוך מחרוזת שמועברת ל־eval כדי שדיווחי שגיאה ימשיכו להצביע על המקור המקורי ולא על הbuffer האנונימי (eval N):

my $code = qq[\n#line ] . __LINE__ . qq[ "] . __FILE__ . qq["\n]
         . q[die "boom"];
eval $code;
# boom at <current file> line <current line>.

הבחנה בין ״הופעל כסקריפט״ ל־״נטען כמודול״ - הבדיקה הנפוצה היא האם הקובץ הופעל ישירות:

__PACKAGE__->run(@ARGV) if __FILE__ eq $0;

מקרי קצה#

  • זמן הידור, לא זמן ריצה. __FILE__ הוא טוקן שהפרסר מחליף בליטרל מחרוזת. הוא אינו פונקציה שניתן לקחת אליה הפניה; \&__FILE__ הוא שגיאת תחביר. ניתן להמיר אותו למחרוזת, לאחסן אותו, או להעביר אותו - אך לא ניתן לדחות את הערכתו.

  • יציב לכל מופע. קריאה לאותה תת־שגרה משני קבצים שונים אינה משנה את ה־__FILE__ שגוף תת־השגרה רואה; ערך זה נאפה לתוך הקוד כאשר תת־השגרה הודרה. אם דרוש שם הקובץ של הקורא, השתמשו ב־caller.

  • הוראות #line כותבות מחדש את הערך. הערה בצורה # line N "NAME" בעמודה אפס מאפסת הן את מספר השורה והן (אופציונלית) את שם הקובץ שהמהדר מדווח. כל טוקן __FILE__ המהודר לאחר הוראה כזו מאמץ את השם החדש. זהו המנגנון שבו משתמשים מחוללי קוד ומנועי תבניות כדי לגרום לשגיאות להצביע על המקור .tt / .pod / .xs המקורי במקום על ה־.pl המחולל.

    # line 1 "config.tt"
    my $x = __FILE__;       # "config.tt"
    

    התחביר המלא של ההוראה מפורט ב־perlsyn תחת Plain Old Comments (Not!).

  • מודולים. בתוך מודול, __FILE__ הוא הנתיב שבו require השתמש כדי לטעון את הקובץ - בדרך כלל מוחלט ותחת שורש @INC. אל תפרסרו אותו כ־Some/Module.pm; השתמשו ב־dirname(__FILE__) אם דרושה הספרייה, לא בניתוח מחרוזות.

  • מקורות שורת־פקודה מיוחדים. קוד מ־-e מדווח -e; קוד מ־-E מדווח גם הוא -e; קוד שמוזן בpipe ב־stdin מדווח -. eval של מחרוזת ללא הוראת #line מדווח (eval N) כאשר N הוא מונה ה־eval.

  • open חד־ארגומנטי וה־__FILE__ הדומה לו. אין מטפל __FILE__; לטוקן אין שום קשר למטפלי קובץ. open(__FILE__) אינו פותח את קובץ המקור הנוכחי - הוא מנסה לפתוח קובץ שנקרא מילולית על שם המחרוזת המורחבת של הטוקן, מה שלעיתים רחוקות הוא הרצוי.

  • אינו ניתן לשינוי בזמן ריצה. השמה ל־__FILE__ היא שגיאת תחביר. המנגנון לשינוי מה ש־__FILE__ מדווח הוא הוראת #line בזמן הידור; אין מקבילה בזמן ריצה.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • __LINE__ - טוקן זמן־הידור מקביל למספר השורה הנוכחי; השניים משמשים כמעט תמיד יחד

  • __PACKAGE__ - טוקן זמן־הידור לשם החבילה הנוכחי, אותה משפחה של טוקנים מיוחדים

  • caller - חיפוש בזמן ריצה של שם הקובץ, השורה והחבילה של הקורא; השתמשו בו כשדרוש מיקום המקור של הקורא ולא שלכם

  • die - מצרף at FILE line LINE. אוטומטית; פנו ל־__FILE__ במפורש רק כאשר אתם מדכאים את הסיומת הזו עם שורה חדשה גוררת

  • perlsyn - הסעיף Plain Old Comments (Not!) מפרט את הוראת #line שכותבת מחדש את __FILE__