האשים

delete#

מסיר את זוג(י) ה־מפתח־ערך הנקוב(ים) מהאש, או אלמנט(ים) ממערך, ומחזיר את מה שהוסר.

delete מגיע לתוך מצרף ומסיר את הרשומות שצוינו לחלוטין - לא רק על־ידי הגדרתן ל־undef. לאחר delete, exists על אותו מפתח או אינדקס מחזיר שקר, keys כבר לא מציג אותו, ואיטרציה על ההאש עם each מדלגת עליו. הארגומנט חייב להיות אלמנט או פרוסה של האש או מערך; הפעולה הסופית שלו בוחרת מה להסיר, וכל מה שמוביל לאותה פעולה (dereference-ים, קריאות מתודה) הוא רק ניווט.

תקציר#

delete $hash{KEY}           # scalar key
delete @hash{LIST}          # hash slice: values of the listed keys
delete %hash{LIST}          # key/value hash slice (5.20+)
delete $array[INDEX]        # array element
delete @array[LIST]         # array slice

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

בהקשר רשימה, delete מחזיר את הערך או הערכים שהוסרו, בסדר הארגומנטים. ארגומנט פרוסה שמפתחו או אינדקסו לא היו קיימים מניב undef במיקום התואם, כך שאורך הרשימה המוחזרת תואם את אורך רשימת המפתחות/אינדקסים.

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

צורת פרוסת ה־מפתח/ערך של 5.20+ של ההאש delete %hash{LIST} מחזירה רשימה של זוגות מפתח/ערך לסירוגין - שני אלמנטים לכל רשומה שנמחקה - מה שהופך אותה לדרך הניבית למשוך קבוצה נקובה של רשומות ולשמור את שני הצדדים.

my %h = (foo => 11, bar => 22, baz => 33);
my $v = delete $h{foo};            # 11
my @v = delete @h{qw(bar quux)};   # (22, undef)
my %kv = delete %h{qw(baz quux)};  # (baz => 33, quux => undef)

מצב גלובלי שהוא נוגע בו#

  • %ENV - delete $ENV{VAR} מבטל את הגדרת משתנה הסביבה עבור התהליך הנוכחי וצאצאיו העתידיים. ההשפעה אמיתית, לא רק על ההאש בצד של Perl; קריאות מערכת רואות את השינוי.

  • מצרפים קשורים - delete מפנה למתודת DELETE של חבילת הקשירה. ערך ההחזרה הוא כל מה שהמימוש בוחר להחזיר; חלק מההאשים הקשורים מחזירים את הערך שנמחק, חלקם לא.

  • $_ - לא מושפע. ל־delete אין ברירת מחדל לדבר; EXPR הוא חובה.

דוגמאות#

הסרת מפתח אחד, בחינה של מה שהיה שם:

my %cfg = (host => "db1", port => 5432, user => "alice");
my $old_host = delete $cfg{host};
# $old_host is "db1"; exists $cfg{host} is false

שחרור זיכרון על־ידי הסרת רשומות רבות בקריאה אחת (פרוסת האש):

delete @cache{@stale_keys};

משיכת קבוצה של רשומות נקובות ושמירת הזוגות (kv-slice של 5.20+):

my %h = (a => 1, b => 2, c => 3);
my %taken = delete %h{qw(a c)};
# %taken is (a => 1, c => 3); %h is (b => 2)

מחיקה דרך מבנה מקונן. הניווט המקדים יכול להיות שרירותי - רק הפעולה הסופית מחליטה מה מוסר:

my $tree = { users => { alice => { roles => [qw(admin ro)] } } };
delete $tree->{users}{alice}{roles}[0];
# roles is now (undef, "ro")
delete $tree->{users}{alice};
# the whole user record is gone

הימנעות מ־autovivification בצד הקריאה תוך כדי הסרה בצד הכתיבה. delete אף פעם לא עושה autovivify להאשים הביניים שדרכם הוא הולך:

delete $h{outer}{inner};    # does not create $h{outer} if absent

השוואה עם splice כשרוצים שהאינדקסים ימוספרו מחדש. delete על אלמנט מערך משאיר חור; splice סוגר את החור:

my @a = (10, 20, 30, 40);
delete $a[1];
# @a is (10, undef, 30, 40); $#a is still 3

my @b = (10, 20, 30, 40);
splice(@b, 1, 1);
# @b is (10, 30, 40); $#b is 2

מקרי קצה#

  • delete מול הצבת undef: $h{k} = undef משאיר את k בהאש עם ערך לא־מוגדר; exists $h{k} עדיין אמת. delete $h{k} מסיר את המפתח לגמרי.

  • מפתח חסר בהקשר סקלר: delete $h{nope} מחזיר undef. זה לא ניתן להבחנה ממחיקת מפתח שערכו היה undef; יש להשתמש ב־exists קודם אם ההבחנה חשובה.

  • each + delete בתוך הלולאה: בטוח כאשר מוחקים רק את המפתח הנוכחי (המפתח שזה עתה הוחזר על־ידי each). מחיקת מפתחות אחרים במהלך איטרציה יכולה לדלג על רשומות או לבקר בהן מחדש - איטרטור ההאש של Perl אינו יציב לאחר שינוי מבני. הכתיבה הבטוחה היא לאסוף מפתחות תחילה:

    for my $k (grep { $h{$_} < 0 } keys %h) {
        delete $h{$k};
    }
    
  • מחיקות מערך גוררות מכווצות את המערך: אם האלמנטים שנמחקו נמצאים בקצה העליון, $#array יורד לאינדקס הגבוה ביותר שעדיין נבדק אמת תחת exists. חורים באמצע נשארים כחורים.

  • delete על מערך אינו מומלץ: הרעיון של ״אינדקס חסר״ אינו קוהרנטי עבור מערכים - אינדקסים הם מיקומיים, לא נקובים. יש להשאיר את הכיווץ של המערך ל־shift, pop, או splice. WARNING ב־POD של upstream מנוסח מחדש: יש להגיע ל־delete של מערך רק כשיודעים שרוצים חור.

  • delete local $h{k}: מסיר את הרשומה עבור הבלוק העוטף ומחזיר אותה על מקומה ביציאה מהתחום. שימושי להסתרה זמנית של מפתחות תצורה מקוד שנקרא בתוך הבלוק מבלי לאבד את הערך המקורי:

    {
        local $ENV{LANG};         # still present, but undef
        delete local $ENV{PATH};  # gone for this block only
        run_thing();
    }   # both restored to original values here
    
  • האש קשור, מערך קשור: delete קורא ל־DELETE; ערך ההחזרה הוא כל מה שמימוש ה־tie מספק. האש DBM קשור מוחק את הרשומה מהדיסק.

  • יעד לקריאה־בלבד: delete על אלמנט לקריאה־בלבד גורם croak עם Modification of a read-only value attempted.

  • הביטוי חייב להסתיים באלמנט או פרוסה: delete $h{k} + 1 היא שגיאת זמן־הידור; ל־delete קדימות נמוכה יותר מאריתמטיקה והוא מצפה לחיפוש מצרף דמוי־lvalue, לא לערך מחושב.

הבדלים מ־upstream#

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

ראו גם#

  • exists - המקבילה לתשאול; יש להשתמש בה לפני delete כאשר צריך להבחין בין ״לא היה שם מעולם״ לבין ״היה שם עם ערך undef״

  • each - איטרטור האש; בטוח לשלב עם delete רק כאשר מוחקים את המפתח הנוכחי

  • keys - תצלום של מפתחות ההאש; הדרך הרגילה לבנות רשימת מחיקה שלא תקיים אינטראקציה עם מצב האיטרטור

  • values - מקבילה ל־keys כשרוצים את קבוצת הערכים שנמחקה ללא המפתחות

  • splice - הכלי הנכון כשרוצים להסיר אלמנטים ממערך וגם למספר מחדש את האינדקסים הנותרים

  • undef - מנקה מצרף שלם (undef %h, undef @a) או סקלר בודד; הדרך המקובלת לרוקן האש או מערך בסיטונאות במקום למחוק כל מפתח