זרימת בקרה

LINE#

טוקן של זמן הידור המוערך למספר השורה שבה הוא מופיע במקור.

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

תקציר#

__LINE__

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

מספר שלם: מספר השורה (1-בסיס) של הטוקן בתוך יחידת ההידור הנוכחית. הערך הוא מספר רגיל, שמיש בכל מקום שבו מספר שמיש - בחישוב אריתמטי, בשיבוץ במחרוזת, כמפתח האש, כארגומנט ל־die או warn.

print __LINE__, "\n";        # prints the line number of this line
my $where = "line " . __LINE__;

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

זמן הידור, לא זמן ריצה#

הערך מוקפא כאשר המקור מהודר. בלבול נפוץ:

sub where { return __LINE__ }     # returns the line where `__LINE__`
                                  # was written, i.e. the `sub` body's
                                  # line - NOT the caller's line

כדי ללכוד את מספר השורה של הקורא, יש להשתמש ב־caller:

sub where { my (undef, undef, $line) = caller; return $line }

בתוך eval של מחרוזת, __LINE__ ממספר את שורות המחרוזת המהודרת (החל מ־1 עבור השורה הראשונה של המחרוזת), לא את שורות הקובץ העוטף.

שינוי מספר השורה המדווח#

מספר השורה ש־__LINE__ מדווח הוא מספר השורה שהלקסר מאמין שהוא נמצא בה. הוראת #line מאפסת אמונה זו:

#line 1000 "virtual.pl"
print __LINE__, "\n";        # prints 1001

#line NNN לבדו קובע רק את מספר השורה; #line NNN "NAME" משנה גם את מה ש־__FILE__ מדווח. מחוללי קוד, מנועי תבניות, ומעבדים מקדימים משתמשים בכך כדי להפנות את האבחנות בחזרה למקור המקורי ולא לקובץ המחולל. ראו Plain Old Comments (Not!) בסעיף perlsyn של מדריך העיון לתחביר המדויק וכללי התיחום.

דוגמאות#

סימון אבחנה עם המקור שלה:

die "bad input at ", __FILE__, " line ", __LINE__, "\n"
    unless defined $x;

die עם הודעה שאינה מסתיימת בשורה חדשה כבר מוסיף " at FILE line LINE.\n". השתמשו בצורה המפורשת לעיל רק כאשר רוצים לשלוט על העיצוב, או כאשר דיכאתם את הסיומת האוטומטית בעזרת שורה חדשה גוררת.

רישום לוג עם קידומת קובץ־ושורה:

sub logf {
    my ($file, $line) = (__FILE__, __LINE__);
    warn "[$file:$line] @_\n";
}

זה רושם בלוג את השורה שבה __LINE__ נכתב - בתוך logf - מה שלעיתים נדירות הוא מה שרוצים. הדפוס הנכון משתמש ב־caller:

sub logf {
    my (undef, $file, $line) = caller;
    warn "[$file:$line] @_\n";
}

יש להשתמש ב־__LINE__ ישירות כאשר מסמנים את פיסת הקוד הזו, לא את הקורא:

print STDERR "checkpoint at line ", __LINE__, "\n";

הזזת אבחנות באמצעות #line:

#line 42 "user-input.pl"
die "syntax error\n";        # dies reporting user-input.pl line 42

מקרי קצה#

  • אינו פונקציה, לא ניתן לקריאה. __LINE__() היא שגיאת תחביר. הטוקן אינו מקבל ארגומנטים ואין לו צורה עם סוגריים.

  • אינו משובץ בתוך מחרוזות במרכאות כפולות. "see line __LINE__" מדפיס את המחרוזת המילולית see line __LINE__. במקום זאת, יש לשרשר: "see line " . __LINE__.

  • אינו bareword תקף של מפתח האש בצורה הקצרה הרגילה. בתוך הקשר מפתח האש של { ... }, $h{__LINE__} עובד כי הטוקן מנותח כביטוי, אבל $h{ __LINE__ } עובד גם הוא וברור יותר. $h{__LINE__ => 1} מנתח את __LINE__ כ־bareword של פסיק שמן (כלומר המחרוזת "__LINE__"), שזה כמעט אף פעם לא מה שרוצים - יש לכתוב (__LINE__, 1) או (__LINE__() => 1) אם רוצים את הערך המילולי.

  • בתוך eval של מחרוזת, __LINE__ סופר משורה 1 של המחרוזת המוערכת. יש להוסיף הוראת #line משלכם בתחילת המחרוזת כדי שהאבחנות יצביעו על הקובץ העוטף:

    my $code = qq{#line @{[__LINE__+1]} "@{[__FILE__]}"\n} . $user_code;
    eval $code;
    
  • בתוך גוף here-doc, __LINE__ מוערך לשורה של ה־<< הפותח בשורה שבה ה־here-doc מאוזכר, לא לשורות בתוך הגוף - גופי here-doc הם נתונים, לא קוד.

  • Heredoc והוראות line. #line בתוך גוף heredoc אין לו השפעה; זה פשוט טקסט. #line עובד רק כהוראת תחילת־שורה בהקשר של קוד.

  • מספרי שורה שליליים או אפס. #line 0 חוקי וגורם לשורה הפיזית הבאה להידווח כשורה 1 (ההוראה עצמה היא שורה 0, השורה שאחריה היא שורה 1). מספרים שליליים מתקבלים אבל מפיקים אבחנות מפתיעות; לא לעשות זאת.

הבדלים מ־upstream#

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

ראו גם#

  • __FILE__ - הטוקן המקביל עבור שם קובץ המקור הנוכחי; השניים כמעט תמיד משמשים יחד

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

  • caller - מקבילה של זמן ריצה כאשר נדרש מספר השורה של הקורא, לא השורה של אתר־הקריאה עצמו

  • die - מוסיף אוטומטית at FILE line LINE כאשר להודעה אין שורה חדשה גוררת, ומסיר את הצורך ב־__LINE__ מפורש

  • warn - אותה התנהגות של איתור־אוטומטי כמו die עבור אבחנות לא־פטליות