PACKAGE#
מחזיר את שם החבילה שבתוקף בנקודה שבה הטוקן מופיע.
__PACKAGE__ הוא ליטרל זמן־הידור: הפרסר מחליף אותו בקבוע מחרוזת שמכיל את שם החבילה שהוראת package האחרונה הכניסה לתוקף עבור התחום הלקסיקלי הזה. הוא לא מחפש דבר בזמן ריצה, לא עוקב אחרי ירושה, ולא איכפת לו באיזו מחלקה הקוד הקורא משתמש - הוא פשוט שם החבילה שבבעלותה נמצא קוד המקור שבו הוא יושב.
תקציר#
__PACKAGE__
__PACKAGE__->some_method(@args)
$__PACKAGE__::VERSION # does NOT work - see Edge cases
מה מקבלים בחזרה#
מחרוזת רגילה שמכילה את שם החבילה המוסמך במלואו (לדוגמה "My::Thing", "main"), מאוחסנת בזמן הידור. הערך הוא קבוע למשך התחום העוטף - הוא אינו יכול להשתנות בזמן ריצה ואינו תלוי באופן שבו הקוד נקרא.
מחוץ לכל הצהרת package מפורשת, הערך הוא "main".
מצב גלובלי שהוא נוגע בו#
אין. __PACKAGE__ נפתר בזמן הידור מהחבילה הלקסיקלית שבתוקף במיקום המקור שלו; הוא לא קורא מצב מפרש בעת ההרצה ואין לו תופעות לוואי.
מדוע להשתמש בטוקן במקום לכתוב את השם#
שלוש סיבות, לפי הסדר שבו נתקלים בהן בפועל:
שם הקובץ מוחלף או שם החבילה מוחלף ושום דבר אחר אינו צריך להשתנות. כל
__PACKAGE__מתעדכן אוטומטית; כל"My::Thing"שהוקלד ביד יש לאתר ולערוך.זו הדרך הניידת היחידה לכתוב ״המחלקה הזו״ בתוך צורת בלוק
package, שבה החבילה מסתיימת בסוגר הסוגר ועוזר פנימי אינו יכול להניח ששם הקובץ תואם.הוא מתחבר היטב עם מתודות מחלקה:
__PACKAGE__->new(...)בעוזר בנאי קורא למחלקה הנכונה בין אם הקובץ נטען ישירות או הועתק לתת־מחלקה שעדיין לא הגדירה מחדש את העוזר.
עבור המקבילה בזמן ריצה - ״לאיזו מחלקה $self בעצם blessed?״ - יש להשתמש ב־ref או, בקוד use feature 'class', ב־__CLASS__. אלו אינם אותו דבר; ראו מקרי קצה.
דוגמאות#
קריאת החבילה הנוכחית בתוך מודול:
package My::Thing;
say __PACKAGE__; # My::Thing
שימוש ב־__PACKAGE__ כדי להגיע למשתנה חבילה בלי לקודד את השם - עמיד מפני שינויי שם:
package My::Thing;
our $VERSION = '1.23';
sub version_string {
no strict 'refs';
return ${ __PACKAGE__ . '::VERSION' };
}
עוזר בנאי שנשאר נכון כשמעתיקים אותו לתת־מחלקה או כשהחבילה מוחלפת בצורת הבלוק:
package My::Widget {
sub new {
my ($class, %args) = @_;
bless { %args, kind => __PACKAGE__ }, $class;
}
}
# kind is always "My::Widget", even if someone calls
# My::Widget::SubClass->new and forgets to override `new`.
מעקב דיבאג שמדפיס מהיכן הגיעה שורת לוג, בלי לשכפל את שם החבילה בכל הודעה:
package My::Worker;
use v5.36;
sub log_debug {
my ($msg) = @_;
warn __PACKAGE__ . ": $msg\n";
}
פתרון חוצה־חבילות עם צורת הבלוק - כל __PACKAGE__ רואה את ה־package שעוטף אותו:
package Outer;
say __PACKAGE__; # Outer
package Inner {
say __PACKAGE__; # Inner
}
say __PACKAGE__; # Outer again
מקרי קצה#
קבוע בזמן הידור, לא משתנה.
__PACKAGE__אינו סקלר;$__PACKAGE__ו־${__PACKAGE__}אינם קיימים. הוא משובץ במחרוזות במרכאות־כפולות כמחרוזת שאליה הוא נפתר:package Foo; say "in @{[__PACKAGE__]}"; # in Foo say "in $__PACKAGE__"; # prints "in " - $__PACKAGE__ is undef
המטבע
@{[ ... ]}הוא הדרך הקצרה ביותר לשבץ אותו.הפניה סימבולית למשתנה חבילה דורשת שרשור מחרוזות, לא שיבוץ של sigil:
no strict 'refs'; my $v = ${ __PACKAGE__ . '::VERSION' }; # works my $v = ${"__PACKAGE__::VERSION"}; # WRONG - literal package
לא אותו דבר כמו
ref $self.__PACKAGE__הוא המקום שבו נכתב המקור;ref $selfהוא המחלקה שהעצם בעצם blessed לתוכה. מתודה הנירשת ממחלקת בסיס מחזירה את מחלקת הבסיס מ־__PACKAGE__אך את תת־המחלקה מ־ref $self:package Base; sub who { (__PACKAGE__, ref $_[0]) } package Child; our @ISA = ('Base'); say join " / ", Child->who; # Base / Child
כאשר רוצים את המחלקה שעליה הופעלה המתודה, יש להשתמש ב־
refעל ה־invocant, ב־__CLASS__בתוך בלוקclass/method, או לקחת את$_[0]/shiftכשם המחלקה עבור מתודת מחלקה.תיחום בצורת בלוק. בתוך
package NAME { ... },__PACKAGE__הואNAME; לאחר הסוגר הסוגר הערך הקודם משוחזר. ראו את הדוגמה המקוננת לעיל.eval STRINGלוכד את חבילת זמן־ההידור שלו. המחרוזת מהודרת בחבילה של הקורא, ולכן__PACKAGE__בתוךeval "..."הוא החבילה שקראה ל־eval:package Foo; eval 'say __PACKAGE__'; # Foo
לפני כל הוראת
package(ראש סקריפט, ראש one-liner),__PACKAGE__הוא"main".__PACKAGE__אינו אומר ״המחלקה הנוכחית״. תחתuse feature 'class', שם המחלקה ושם החבילה תואמים בשורת ההצהרה אך יכולים להיות שונים באתר קריאה שמופעל על תת־מחלקה. בתוךmethod, עדיף__CLASS__כאשר רוצים את המחלקה של המקבל.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
package- ההצהרה שקובעת מה__PACKAGE__מחזיר; כל ערך שאינוmainמגיע מאחת כזו__CLASS__- המקבילה בזמן ריצה עבור קוד בתוך בלוקclass: מחזיר את המחלקה של המופע המפעיל, שעשוי להיות תת־מחלקהref- שואלים עצם לאיזו מחלקה הוא blessed; הכלי הנכון כאשר יש$selfורוצים את המחלקה שלו בפועלcaller- החבילה הקוראת בזמן ריצה; יש להשתמש כאשר צריך את החבילה של הקורא, לא את שלכםbless- הפרימיטיב שהופך הפניה לעצם של חבילה נתונה; בדרך כלל משולב עם בנאים בסגנון__PACKAGE__->new(...)our- מצהיר על כינוי לקסיקלי למשתנה חבילה בחבילת זמן־ההידור הנוכחית (אותה חבילה ש־__PACKAGE__נוקב בשמה)