each#
לעבור דרך האש או מערך רשומה אחת בכל פעם.
each מקדם איטרטור פר־מכולה ומחזיר את הרשומה הבאה. עבור האש רשומה זו היא זוג (key, value); עבור מערך זה זוג (index, value). כאשר האיטרטור עבר את כל הרשומות, הקריאה הבאה מחזירה את הרשימה הריקה (או undef בהקשר סקלרי) ואז מתאפס, כך שלולאת while (each ...) חדשה מתחילה מההתחלה. סדר ההאש אקראי לכל תהליך ולכל האש; סדר המערך הוא בקפדנות מאינדקס הנמוך ביותר ראשון.
תקציר#
while (my ($k, $v) = each %h) { ... }
while (my ($i, $v) = each @a) { ... }
while (each %h) { ... } # sets $_ to the key
my $k = each %h; # scalar context: key/index only
מה מקבלים בחזרה#
הקשר רשימה: רשימה דו־אלמנטית
($key, $value)עבור האש,($index, $value)עבור מערך. במיצוי, הרשימה הריקה.הקשר סקלרי: המפתח (עבור האש) או האינדקס (עבור מערך). במיצוי,
undef.each %hחשוף בתנאיwhile/for: בודק מוגדרוּת של המפתח/אינדקס המוחזר, לא אמת, ומשייך את המפתח ל־$_. זה מה שגורם ל־while (each %h) { print "$_\n" }לעבוד גם כאשר המפתח הוא מחרוזת ריקה או0.
לאחר מיצוי האיטרטור מתאפס באופן משתמע, כך שהקריאה אחרי זו שהחזירה ריק מתחילה איטרציה מחדש מהראש.
מצב גלובלי שהוא נוגע בו#
כל האש וכל מערך נושאים איטרטור פנימי משלהם. each, keys, ו־values כולם מקדמים ומשתפים את אותו איטרטור - הם שלוש מבטים על אותו סמן, לא שלוש לולאות עצמאיות. זוהי העובדה החשובה ביותר היחידה לגבי each:
קריאה ל־
keys %hאוvalues %h(בכל הקשר, אפילו כספירה חד־פעמית כמוscalar keys %h) מאפסת את האיטרטור של ההאש. לולאתwhile (each %h)שמופרעת על־ידיscalar keys %hבגוף תתחיל מחדש מהראש באיטרציה הבאה - או גרוע מכך, תיכנס ללולאה אינסופית.התייחסות להאש בהקשר רשימה מאפסת גם את האיטרטור שלו (לדוגמה
my @copy = %h, או העברת%hלתת־שגרה). איטרטורים של מערך אינם מתאפסים על־ידי התייחסות בהקשר רשימה.שתי לולאות שעוברות על אותו
%hחולקות סמן אחד. קינוןwhile (each %h) { ... while (each %h) { ... } ... }מבקר בכל רשומה לכל היותר פעם אחת בסך הכל, לאn * mפעמים.האש/מערך אנונימי בתנאי (
each %{ +{ a => 1 } }) בונה מכולה חדשה בכל איטרציה, כך שהאיטרטור תמיד טרי - הלולאה לעולם לא מסתיימת.הצורה החשופה של
eachמשייכת ל־$_; אם מסתמכים על$_במקום אחר בגוף הלולאה, יש לשמור אותו עםlocal.
כל כניסה ללולאת while (each ...) קולטת את עמדת האיטרטור שהמכולה נמצאת בה. אין דרך לבודד את האיטרטור של הלולאה מקוד אחר שנוגע באותה מכולה. אם גוף הלולאה קורא לפונקציה שעשויה לקרוא את אותו האש, התבנית הבטוחה היא לולאת foreach על keys במקום זאת.
דוגמאות#
איטרציה בסיסית של האש:
my %colour = (red => "#f00", green => "#0f0", blue => "#00f");
while (my ($name, $hex) = each %colour) {
print "$name = $hex\n";
}
# order is unspecified
איטרציה של מערך (Perl 5.12+):
my @letters = ('a' .. 'e');
while (my ($i, $c) = each @letters) {
print "[$i] $c\n";
}
# [0] a
# [1] b
# [2] c
# [3] d
# [4] e
הדפסת האש בסדר ממוין - each אינו ממיין, אז יש לפנות ל־keys ועוד sort במקום זאת:
for my $k (sort keys %colour) {
print "$k = $colour{$k}\n";
}
each חשוף בתנאי while, אשר מגדיר את $_ למפתח בכל איטרציה (Perl 5.18+):
while (each %ENV) {
print "$_=$ENV{$_}\n";
}
מחיקה בטוחה במהלך איטרציה - ניתן למחוק את המפתח שזה עתה הוחזר על־ידי each מבלי להפריע לסמן:
while (my ($key, $value) = each %hash) {
delete $hash{$key} if $value < 0; # safe
}
איטרציה של האש עם לולאת foreach כאשר משהו בגוף עלול לגעת ב־%hash (התבנית האיתנה - לתפוס תמונת מצב של המפתחות קודם):
for my $key (keys %hash) {
my $value = $hash{$key};
# body is free to read %hash, call subs that read it, even
# mutate it cautiously - our iteration list is fixed already.
}
foreach רב־ערכי על האש (Perl 5.36+), שהופך את each למיותר ברוב הלולאות ועוקף את מלכודת האיטרטור המשותף:
foreach my ($key, $value) (%hash) {
print "$key => $value\n";
}
מקרי קצה#
איטרטור לא מתאפס בין כניסות מחדש: לולאת
while (each %h)שיוצאת מוקדם דרךlast,return, אוdieמשאירה את האיטרטור באמצע מעבר. ה־while (each %h)הבא על אותו האש קולט מאיפה שהראשון הפסיק, לא בהתחלה. יש לקרוא ל־keys %hבהקשר void -keys %h;- כדי לאלץ איפוס לפני הלולאה החדשה.keys/valuesמאפסים את האיטרטור: כל קריאה ל־keysאוvaluesעל אותו האש - כוללscalar keys %hבתוך גוף הלולאה - מאפסת את הסמן.התייחסות בהקשר רשימה מאפסת את האיטרטור של האש, לא של מערך:
my @flat = %hמאפס את הסמן של%h; המקבילהmy @copy = @aלא נוגעת באיטרטור של@a.מחיקה־במהלך־איטרציה אינה מוגדרת למעט הרשומה שהוחזרה לאחרונה. מחיקת מפתח אחר עלולה לגרום לרשומות להיות מבוקרות פעמיים או מדולגות לחלוטין.
הוספה־במהלך־איטרציה אינה מוגדרת - הוספת מפתח חדש באמצע הלולאה עשויה או לא להיות מבוקרת, ועלולה להפריע לסדר רשומות שעדיין לא נראו.
מכולה אנונימית בתנאי:
each %{ +{ a => 1 } }אוeach @{ [1,2,3] }בונה מכולה טרייה בכל פעם שהתנאי מוערך, כך שהאיטרטור תמיד חדש והלולאה לעולם לא מסתיימת.האשים ומערכים קשורים (tied) מאצילים ל־
FIRSTKEY/NEXTKEY(האשים) אוFETCHSIZE/FETCH(מערכים), כך שסדר האיטרציה הוא מה שהמחלקה הקשורה בוחרת ואף אחת מהערבויות לעיל אינה בהכרח בתוקף.מוגדרוּת מול אמת בתנאי הלולאה:
while (each %h)ו־while (my $k = each %h)שניהם בודקים מוגדרוּת של הביטוי, כך שמפתח"0"או""אינו מסיים את הלולאה. זהו מקרה מיוחד עבורeachבמפורש.ביטויים סקלריים:
each $hrefעל סקלר שמחזיק הפניה היה תכונה ניסיונית ב־5.14 והוסר ב־5.24. יש לבצע dereference במפורש:each %$href,each @$aref.מצב משותף בין תת־שגרות: העברת
%hלתת־שגרה שקוראת ל־each %h,keys %h, אוvalues %hעליו מפריעה לאיטרטור של הקורא. אם מפרסמים האש, יש להניח שקוראים עלולים לשבור את הלולאה; עדיףforeach (keys ...)לאיתנות.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
keys- תמונת מצב של כל המפתחות (האש) או האינדקסים (מערך); מאפס את האיטרטור ש־eachמשתמש בוvalues- תמונת מצב של כל הערכים; מאפס את האיטרטור ש־eachמשתמש בוdelete- בטוח עבור הרשומה שזה עתה הוחזרה על־ידיeach, לא בטוח לכל אחרת במהלך איטרציהexists- לבדוק שייכות מפתח/אינדקס מבלי להפריע לאיטרטורfor/foreach- הלולאה הבטוחה יותר כאשר הגוף עלול לגעת במכולה; יש לשלב עםkeysכדי לתפוס תמונת מצב קודםsort- לשייך עםkeysכאשר נדרש סדר איטרציה מוגדר;eachלעולם לא ממיין