ref#
מחזיר מחרוזת המתארת על מה הפניה מצביעה.
ref בוחן את האופרנד שלו ומחזיר מחרוזת המזהה את סוג הישות המוצבעת. עבור הפניה ש־blessed עליה הוא מחזיר את שם המחלקה; עבור הפניה שאינה blessed הוא מחזיר אחת ממחרוזות הטיפוס הפנימיות (SCALAR, ARRAY, HASH, CODE, GLOB, LVALUE, IO, FORMAT, REF, VSTRING, REGEXP). עבור כל דבר שאינו הפניה הוא מחזיר את המחרוזת הריקה. ללא ארגומנט, ref פועל על $_.
תקציר#
ref EXPR
ref
מה מקבלים בחזרה#
מחרוזת. שלוש קטגוריות זרות זו לזו:
הפניה ש־blessed עליה - שם המחלקה שאל תוכה הישות המוצבעת blessed. לדוגמה, הפניה
bless {}, 'Dog'מחזירה"Dog". תת־מחלקות מחזירות את שמן שלהן, לא של ההורה: הפניה ש־blessed עליה לתוךPuppy(ISAשלDog) מחזירה"Puppy". ראוbless.הפניה שאינה blessed - אחת ממחרוזות הטיפוס הפנימיות המפורטות למטה, המזהה את הטיפוס הפיזי של הישות המוצבעת.
לא־הפניה - המחרוזת הריקה
"".
המחרוזת הריקה היא ערך השקר היחיד ש־ref אי־פעם מחזיר, ולכן if (ref $x) היא בדיקת ״האם זוהי הפניה?״ בטוחה. ראו את סעיף מקרי הקצה להסבר מדוע if (ref $x eq 'HASH') אינה בדיקת ״האם זוהי הפניית האש?״ בטוחה.
מחרוזות טיפוס פנימיות#
מוחזרות עבור הפניות שאינן blessed בהתאם לישות הפיזית המוצבעת:
מחרוזת | ישות מוצבעת |
|---|---|
| הפניה לסקלר רגיל |
| הפניה למערך |
| הפניה להאש |
| הפניה לתת־שגרה |
| הפניה ל־typeglob |
| הפניה לביטוי שניתן להשמה |
| הפניה למטפל קלט/פלט |
| הפניה ל־format |
| הפניה להפניה אחרת |
| הפניה לסקלר v-string |
| הפניה ל־regexp גולמי (לא־blessed) |
regex מהודר מ־qr// הוא blessed לתוך המחלקה Regexp בזמן היצירה, אז ref qr/.../ מחזיר בדרך כלל "Regexp", לא "REGEXP". המחרוזת REGEXP העירומה מופיעה רק עבור ישויות regex לא־blessed, שהן נדירות מחוץ למימוש הפנימי.
דוגמאות#
בחינות טיפוס בסיסיות:
ref \1 # "SCALAR"
ref [] # "ARRAY"
ref {} # "HASH"
ref sub { } # "CODE"
ref \*STDOUT # "GLOB"
ref \\1 # "REF" (reference to a reference)
ref qr/foo/ # "Regexp" (blessed)
ref "plain string" # "" (not a reference)
ref 42 # ""
ref undef # ""
הפניות ש־blessed עליהן מחזירות את שם המחלקה:
my $obj = bless {}, 'My::Widget';
ref $obj; # "My::Widget"
שמירה לפני dereferencing:
sub stringify {
my ($v) = @_;
return "[undef]" if !defined $v;
return "[ref: " . ref($v) . "]" if ref $v;
return $v;
}
צורה ללא־ארגומנט קוראת את $_:
for my $item (@things) {
print "skipping non-ref\n" and next unless ref;
...
}
בחירת הבדיקה הנכונה#
ref הוא הפרימיטיב הוותיק ביותר של בחינה־עצמית בשפה והוא מערבב שלוש שאלות שונות. קוד מודרני צריך לבחור את האופרטור התואם את השאלה הנשאלת.
האם זוהי הפניה בכלל?
if (ref $x) { ... } # empty string is the only false return
האם זה עצם של (או נגזר מ־) מחלקה נתונה? השתמשו באופרטור isa (או המתודה UNIVERSAL::isa) - הוא סורק את @ISA ומכבד תת־מחלוּת, מה שהשוואת ref מילולית אינה עושה:
if ($obj isa 'My::Widget') { ... } # true for subclasses too
if ($obj->isa('My::Widget')) { ... } # method form
if (ref($obj) eq 'My::Widget') { ... } # FRAGILE: fails for subclasses
מהו הטיפוס הפיזי הבסיסי, ללא תלות ב־blessing? השתמשו ב־Scalar::Util::reftype - הוא מתעלם מהמחלקה ומחזיר את מחרוזת הטיפוס הפנימית אפילו עבור הפניות ש־blessed עליהן:
use Scalar::Util qw(reftype blessed);
reftype($obj); # "HASH" if $obj is blessed hash ref
blessed($obj); # class name, or undef if not blessed
מקרי קצה#
לעולם אל תשתמשו ב־
refכערך אמת של הישות המוצבעת. הפניה ש־blessed עליה לתוך מחלקה ששמה מילולית0גורמת ל־ref $objלהחזיר את המחרוזת"0", שהיא שקרית. זה נדיר בעיצוב אבל ה־foot-gun הוא ישן וידוע. השוו למחרוזת הריקה במקום:if (ref $x ne "").שמות מחלקה מתנגשים עם מחרוזות טיפוס פנימיות. דבר אינו מונע מכם לכתוב
package HASH; sub new { bless {}, shift }. ואזref(HASH->new)מחזיר"HASH"- בלתי ניתן להבחנה מהפניה לא־blessed להאש על־ידיrefלבדו. השתמשו ב־Scalar::Util::blessedכדי לפענח את העמימות, או ב־reftypeכדי לשאול את שאלת הטיפוס־הפיזי ישירות.refעלqr//מחזיר"Regexp", לא"REGEXP". עצמיqr//הם blessed בבנייה; הצורה הגדולה מופקת רק עבור ההפניה ה־(לא־רגילה) ל־regex לא־blessed.משתנים שעברו tie:
refרואה דרך ה־tie אל ההפניה הבסיסית. השתמשו ב־tiedכדי לאחזר את העצם שמגבה את ה־tie.הפניות חלשות הן עדיין הפניות:
refמתנהג זהה עבור refs חלשות וחזקות. השתמשו ב־Scalar::Util::isweakלזיהוי חולשה.Stringification ש־overloaded אינו משפיע על
ref. ערך ההחזרה שלrefמופק על־ידי ה־runtime, לא על־ידי ה־overload של""של העצם.ל־
ref EXPRיש קדימות גבוהה מאוד - הוא מפוענח כאופרטור אונרי בעל שם. השתמשו בסוגריים כשהארגומנט הוא משהו מורכב יותר ממשתנה פשוט:ref $a || $b; # parsed as (ref $a) || $b ref($a || $b); # what you probably meant
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
bless- התקנת שם מחלקה על הפניה; השם שמותקן כאן הוא בדיוק מה ש־refמחזיר לאחר מכןisa- בדיקת חברות במחלקה המכבדת ירושת@ISA; העדיפו זאת על־פניref(...) eq 'ClassName'ל־OO dispatchtied- אחזור העצם המממש משתנה שעבר tie;refעל סקלר שעבר tie עוקב אחר ה־tie אל הישות המוצבעתScalar::Util::reftype- מחרוזת טיפוס־פיזי עבור הפניה, מתעלמת מ־blessingScalar::Util::blessed- שם המחלקה אם blessed,undefאחרת; המקבילה החד־משמעית ל־refעבור קוד OOperlref,perlobj- מדריכי עיון להפניות ולמודל העצמים