undef#
הערך הלא־מוגדר, והאופרטור שמפיק אותו.
ל־undef יש שני כובעים. undef חשוף הוא ערך - הסקלר הלא־מוגדר הקנוני, הדבר ש־defined מחזיר עליו שקר. undef EXPR הוא אופרטור אונארי המבטל את ההגדרה של הארגומנט שלו במקום: המשתנה, המערך, ההאש, תת־השגרה, או ה־typeglob הקרויים ב־EXPR מתרוקנים, ובמקום שאפשר, האחסון שלהם משוחרר.
שתי הצורות מוערכות לערך הלא־מוגדר.
תקציר#
undef # the undefined value
undef EXPR # undefine the lvalue EXPR, return undef
EXPR חייב להיות lvalue: סקלר, מערך (עם @), האש (עם %), תת־שגרה (עם &), או typeglob (עם *).
מה מקבלים בחזרה#
תמיד הערך הלא־מוגדר. צורת האופרטור מחזירה undef לאחר מחיקת הארגומנט שלה; צורת הערך פשוט מוסרת לכם undef.
my $x = undef; # $x is now undef
return undef if $oops; # explicit "I mean no value"
my $was = undef $counter; # $counter wiped, $was is undef
הערך לעומת האופרטור#
undef חשוף הוא הסקלר הלא־מוגדר. השמתו למשתנה משאירה את האחסון של המשתנה במקומו וקובעת את ערכו ל־undef:
my @big = (1) x 1_000_000;
$big[0] = undef; # slot 0 holds undef; @big still huge
@big = (); # empties the array, keeps the AV
@big = undef; # assigns the ONE-element list (undef)
שימו לב לשורה האחרונה: @big = undef היא השמת רשימה של רשימה בעלת אלמנט אחד שהאלמנט היחיד שלה הוא undef, ולכן @big נגמר באורך 1. כמעט אף פעם זה אינו מה שאתם רוצים. השתמשו ב־@big = () כדי לרוקן, או ב־undef @big כדי לרוקן וגם לשחרר את האחסון הגיבוי.
צורת האופרטור עושה יותר מאשר להשים undef:
undef $scalar; # scalar: sets value to undef, frees any PV buffer
undef @array; # array: frees all elements AND the AV's storage
undef %hash; # hash: frees all entries AND the HV's buckets
undef ⊂ # sub: frees the CV body; the name still exists
undef *glob; # glob: destroys $glob, @glob, %glob, &glob, etc.
ההבחנה משנה לזיכרון. @array = () משאיר את הקיבולת המוקצה ללא שינוי כך שה־push הבא זול; undef @array משחרר אותה. למערך גדול וחד־פעמי שאתם רוצים באמת לשחרר, השתמשו ב־undef. למערך עבודה שתמלאו מחדש, השתמשו ב־= ().
דוגמאות#
החזרת ״ללא ערך״ מתת־שגרה. בהקשר סקלר זוהי דרך נקייה לאותת כשל; בהקשר רשימה undef לבדו מפיק רשימה בעלת אלמנט אחד המכילה undef, שהיא אמת:
sub find_user {
my ($id) = @_;
return undef unless $id; # scalar-context caller: false
...
}
לתת־שגרות שנועדו לאותת כשל בשני ההקשרים, החזירו רשימה ריקה במקום - return ללא ארגומנט עושה את הדבר הנכון:
sub find_user {
my ($id) = @_;
return unless $id; # () in list ctx, undef in scalar ctx
...
}
דילוג על ערכים מיקומיים בהשמת רשימה. undef בצד השמאלי של השמת רשימה הוא placeholder שמשליך את הערך התואם:
my ($x, undef, $z) = foo(); # discard the middle value
my (undef, @rest) = @_; # drop the first arg, keep the rest
ניב select קלאסי ל־sleep תת־שנייה - שלוש קבוצות מטפלי קובץ שמתעלמים מהן בתוספת timeout:
select undef, undef, undef, 0.25; # sleep 250 ms
החזרה דו־הקשרית:
return wantarray ? (undef, $errmsg) : undef if $they_blew_it;
שחרור קבוצת עבודה גדולה:
my %cache = build_huge_cache();
use_cache(\%cache);
undef %cache; # free buckets and entries now
ביטול הגדרה של תת־שגרה. השם בטבלת הסמלים נשאר, אך קריאה אליו תתלונן על תת־שגרה לא־מוגדרת:
sub greet { print "hi\n" }
undef &greet;
greet(); # Undefined subroutine &main::greet
ביטול הגדרה של typeglob מוחק את כל החריצים בבת אחת:
our $xyz = 1;
our @xyz = (1, 2);
our %xyz = (a => 1);
sub xyz { 42 }
undef *xyz; # $xyz, @xyz, %xyz, &xyz all gone
מקרי קצה#
undef $hash{$key}אינוdelete. הוא קובע את הערך באותו מפתח ל־undef; המפתח עצמו עדיין קיים ו־existsעדיין מחזיר אמת. השתמשו ב־delete $hash{$key}כדי להסיר את המפתח. אותו דבר חל על אלמנטי מערך:undef $arr[3]משאיר את אינדקס 3 במקומו עם ערך undef, הוא אינו מקצר את המערך.על משתנים קשורים וערכי DBM,
undef $tied{$key}מפעיל את ה־STOREשל ה־tie, לא את ה־DELETEשלו. אזהרת ה־perldoc (״probably not do what you expect on most predefined variables or DBM list values״) היא ספציפית על כך.undefהוא אופרטור אונארי, לא אופרטור רשימה. הוא לוקח בדיוק ארגומנט אחד, ולכןundef $a, $bמתפענח כ־(undef $a), $b- רק$aהופך ללא־מוגדר. כדי לבטל הגדרה של מספר משתנים, קראו לו מספר פעמים, או השתמשו בלולאה:undef $_ for $a, $b, $c;
undef EXPRדורש lvalue.undef 42אוundef func()הם שגיאת זמן הידור (Can’t modify … in undef operator).undefבצד השמאלי בהשמת רשימה הוא תחביר, לא ערך.(undef, $x) = @pairמתפענח באופן מיוחד; לא ניתן לכתובmy $slot = undef; ($slot, $x) = @pairולצפות שהערך הראשון יושלך - זה משים לתוך$slot.undefקבוע בהקשר בוליאני הוא שקר, בהקשר מספרי הוא0, בהקשר מחרוזת הוא"". תחתuse warningsכל אחת מההמרות הללו פולטת אזהרתUse of uninitialized valueבנקודת השימוש, לא בנקודה שבה המשתנה הפך ל־undef.undef &subאינו מסיר את שם תת־השגרה מ־stash החבילה שלה - רק את הקוד. כדי להסיר גם את השם, בטלו את הגדרת כל חריץ ה־glob:delete $Package::{sub_name}אוundef *Package::sub_nameאם אתם רוצים גם את חריצי האחים נעלמים.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
defined- הפרדיקט השואל ״האם הערך הזה אינו undef?״; המקבילה הטבעית לערךundefdelete- הסרת מפתח האש או אלמנט מערך לחלוטין; השתמשו בזה, לא ב־undef, כאשר אתם רוצים ש־existsיהפוך לשקרexists- בדיקה אם מפתח האש או אינדקס מערך קיים, ללא קשר אם ערכו מוגדרlocal- החלפה זמנית של ערך משתנה חבילה (לעיתים קרובות ב־undef) למשך תחוםwantarray- מזווג עםundefבהחזרת כשל דו־הקשרית הניביתwantarray ? (undef, $err) : undef