bless#
מסמן את הדבר שעליו מצביעה ההפניה כעצם בחבילה.
bless משייך את הישות המוצבעת של REF לחבילה הנקובה בשם CLASSNAME, כך שקריאות מתודה דרך REF מבצעות דיספאץ« מול תת־השגרות של אותה חבילה (ואבותיה ב־@ISA). ההפניה עצמה אינה משתנה; מה שמשתנה הוא תג המחלקה של הישות המוצבעת. bless מחזיר את REF, ולכן הוא כמעט תמיד ההוראה האחרונה בבנאי.
תקציר#
bless REF, CLASSNAME
bless REF
מה מקבלים בחזרה#
אותה הפניה שהועברה כארגומנט הראשון, כעת נושאת את תג המחלקה של CLASSNAME. החזרת ההפניה מאפשרת לבצע tail call ל־bless מבנאי:
sub new {
my ($class, %args) = @_;
return bless { %args }, $class;
}
מאותה נקודה ואילך, ref על ההפניה המוחזרת מניב את שם המחלקה ולא את סוג ההפניה הגולמי (HASH, ARRAY, CODE, …).
צורות#
שתי צורות קריאה, אחת מועדפת בחוזקה:
דו־ארגומנטית - תמיד להשתמש בזו.
bless $ref, $class;
הישות המוצבעת הופכת לעצם בחבילה הנקובה בשם
$class. שימוש בארגומנט הראשון של הבנאי ($_[0], ככלל$class) שומר על הבנאי כניתן לירושה: תת־מחלקה שקוראת ל־Parent::new('Child', ...)מקבלת בחזרה עצם שעבר bless לתוךChild, לא לתוךParent.דו־ארגומנטית עם מחרוזת ריקה - bless לתוך
main.bless $ref, "";
CLASSNAMEריק מטופל כחבילתmain. שימושי לעיתים נדירות מחוץ לתחבולות מכוונות.חד־ארגומנטית - לא מומלצת.
bless $ref;
הישות המוצבעת עוברת bless לתוך החבילה הנוכחית (החבילה שבה הקריאה ל־
blessמהודרת). דבר זה שובר ירושה: תת־מחלקה שיורשת בנאיblessחד־ארגומנטי עדיין מסיימת עם עצמים בחבילה של ההורה, לא של הקורא. יש להשתמש בצורה הדו־ארגומנטית אלא אם יש סיבה קונקרטית שלא לעשות זאת, ולתעד את הסיבה.
דוגמאות#
מחלקה מינימלית מבוססת האש:
package Point;
sub new {
my ($class, $x, $y) = @_;
return bless { x => $x, y => $y }, $class;
}
sub x { $_[0]->{x} }
sub y { $_[0]->{y} }
package main;
my $p = Point->new(3, 4);
print ref $p, "\n"; # Point
print $p->x, ",", $p->y; # 3,4
בנאי בר־ירושה - אותו new עובד עבור תת־מחלקה ללא שינוי:
package Shape;
sub new {
my ($class, %args) = @_;
return bless { %args }, $class;
}
package Circle;
our @ISA = ('Shape');
sub area {
my $self = shift;
return 3.14159 * $self->{radius} ** 2;
}
package main;
my $c = Circle->new(radius => 5);
print ref $c, "\n"; # Circle
print $c->area, "\n"; # 78.53975
עצמים מבוססי מערך עובדים באותו אופן - כל סוג הפניה ניתן ל־bless:
package Pair;
sub new {
my ($class, $a, $b) = @_;
return bless [$a, $b], $class;
}
sub first { $_[0]->[0] }
sub second { $_[0]->[1] }
my $p = Pair->new("left", "right");
print $p->first, "/", $p->second; # left/right
ביצוע bless מחדש לעצם קיים משנה את תג המחלקה שלו במקום:
my $obj = bless {}, 'OldClass';
bless $obj, 'NewClass';
print ref $obj; # NewClass
bless מחזיר את ההפניה, ולכן שרשור לקריאות מתודה באותה שורה עובד:
Logger->new(file => $path)->info("started");
# ^ called on the blessed ref
מקרי קצה#
ההפניה היא מה שמתויג, לא המשתנה. עותקים של ההפניה חולקים את תג המחלקה משום שכולם מצביעים לאותה ישות מוצבעת:
my $a = bless {}, 'Foo'; my $b = $a; print ref $b; # Foo
ביצוע bless מחדש מותר ומיידי. ניתן לבצע bless להפניה כמה פעמים שרוצים; כל קריאה דורסת את תג המחלקה הקודם. אין built-in של ״unbless״ - יש לבצע bless מחדש לחבילה ניטרלית אם צריך להסיר עצמיות מישות מוצבעת שעדיין מחזיקים אליה הפניות.
CLASSNAMEשל""משמעוmain. מפורש ורצוי לעיתים נדירות; בדרך כלל סימן ששם מחלקה מחושב יצא ריק בטעות.יש להימנע מ־
bless $ref, "0". שם המחלקה"0"הוא ערך שקרי, ולכן קוד שבודקif (ref $obj) { ... }יפרש את העצם בטעות כ״לא הפניה״. יש לבחור כל שם מחלקה שאינו שקרי.מוסכמת רישיות שם־מחלקה. יש להשתמש ברישיות מעורבת (
My::Package). שמות ALL-CAPS שמורים לטיפוסי built-in של Perl (SCALAR,ARRAY,HASH,CODE, …) ושמות ברישיות־קטנה שמורים לפראגמות (strict,warnings,utf8). ביצוע bless לכל אחד ממרחבי שמות אלה מזמין בלבול עם מנגנוני רמת השפה.ארגומנט ראשון שאינו הפניה הוא שגיאה קטלנית.
bless 42, 'Foo'מת עםCan't bless non-reference value. הארגומנט הראשון חייב להיות הפניה.blessחד־ארגומנטי בוחר את חבילת זמן־ההידור. הוא משתמש בחבילה שהקריאה ל־blessנמצאת בתוכה לקסיקלית - לא חבילת הקורא, לא חבילתו של$class. בדיוק בגלל זה הוא שובר ירושה ובגלל זה הצורה הדו־ארגומנטית קיימת.הפניות חלשות ו־blessing מתקשרות כצפוי.
Scalar::Util::weakenעל הפניה blessed לא מבטלת אותה; החריץ המוחלש עדיין רואה את תג המחלקה, ו־refעובד עד שהישות המוצבעת מושמדת.DESTROYנורה על הישות המוצבעת ה־blessed. כאשר ההפניה האחרונה לישות מוצבעת blessed נעלמת, Perl קורא ל־DESTROYבמחלקה של ההפניה (בהליכה אחר@ISA). שינוי המחלקה ב־blessמאוחר משנה איזהDESTROYרץ.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
ref- קריאת תג המחלקה בחזרה מהפניה blessed, או סוג ההפניה (HASH,ARRAY, …) עבור הפניה לא־blessedpackage- הצהרה על החבילה שאליה מהדרת קריאה ל־blessאו הגדרת תת־שגרה; היעד שלblessחד־ארגומנטיclass- ה־built-in הניסיוני לתחביר מחלקה שמחליף את תבנית הבנאי הידניתpackage+blessבתחביר דקלרטיביtie- צורה שונה של קסם לכל־משתנה; לא קשורה ל־blessלמרות המסגור השטחי של ״חיבור התנהגות לערך״@ISA- שרשרת הירושה המתייעצים בה בעת ביצוע דיספאץ« לקריאת מתודה על הפניה blessedDESTROY- מתודת ההורס ש־Perl קורא לה על הישות המוצבעת ה־blessed כאשר ההפניה האחרונה אליה נעלמת; מוצהרת כתת־שגרה בתוך חבילת המחלקה