shift#
הסרה והחזרה של האלמנט הראשון של מערך.
shift משנה את הארגומנט שלו: הוא מסיר את האלמנט באינדקס 0, מזיז כל אלמנט נותר למטה במיקום אחד, ומחזיר את הערך שהוסר. המערך מתכווץ באחד. אם המערך ריק, דבר אינו מוסר ומוחזר undef.
תקציר#
shift @arr
shift @$aref
shift # @_ inside a sub, @ARGV outside
מה מקבלים בחזרה#
הסקלר שהיה באינדקס 0, או undef אם המערך היה ריק. מכיוון ש־undef הוא גם אלמנט מערך חוקי, החזרת undef חשופה אינה משמעה בפני עצמה שהמערך היה ריק - השתמשו ב־scalar @arr או בבדיקת defined מוקדמת כשההבחנה משנה:
my @arr = (undef, 'two');
my $item = shift @arr; # undef - but @arr was not empty
מערך ברירת מחדל: @ARGV לעומת @_#
נקרא ללא ארגומנט, shift בוחר את המערך שלו מההקשר הסובב:
בתוך תת־שגרה שמית או אנונימית -
@_. זו הדרך הניבית לצרוך ארגומנטים מיקומיים בזה אחר זה.Outside any sub (including in the file scope of a script, and in
eval STRING,BEGIN,INIT,CHECK,UNITCHECK,ENDblocks)@ARGV. This is how top-of-script argument consumption is usually written.
הבחירה נעשית בזמן הידור על בסיס מיקום לקסיקלי, לא בזמן ריצה. shift בתוך sub תמיד מכוון ל־@_ גם אם ה־sub נקרא מתחום הקובץ.
דוגמאות#
צריכת ארגומנט מיקומי בודד בתוך מתודה. זוהי השורה הראשונה הקנונית של כמעט כל מתודה מונחית־עצמים ב־Perl:
sub greet {
my $self = shift;
my $name = shift;
return "hello, $name, from $self";
}
אותה מתודה כתובה עם פרוסת @_ של list-unpack. שתי הצורות הן ניביות; shift מנצח כשרוצים לקלף את ה־invocant לפני שמחליטים מה לעשות עם שאר @_:
sub greet {
my ($self, $name) = @_;
return "hello, $name, from $self";
}
צריכת @ARGV בראש סקריפט, ארגומנט אחד בכל פעם:
my $mode = shift // 'default'; # first CLI arg, or 'default'
my $path = shift // die "need a path\n";
# @ARGV now holds whatever is left
תור FIFO: push על הזנב, shift מהראש:
my @queue;
push @queue, 'a', 'b', 'c';
while (defined(my $job = shift @queue)) {
handle($job);
}
Dereference של הפניה למערך במקום - shift עובד על @$aref בדיוק כמו על מערך שמי:
my $aref = [10, 20, 30];
my $head = shift @$aref; # 10, $aref now [20, 30]
מקרי קצה#
מערך ריק: מחזיר
undefומשאיר את המערך ללא שינוי.shiftעל מערך ריק אינו שגיאה.מורכבות היא O(n): כל אלמנט נותר מוזז למטה בחריץ אחד. עבור מערכים גדולים המשמשים כתורים זה מצטבר. כאשר סדר FIFO אינו דרוש,
popהוא O(1); כאשר הוא דרוש, שקלו מבנה נתונים בסגנון deque או צמד מחסניות במקום לבצעshiftעל מערך בן מיליון אלמנטים בלולאה.shiftללא ארגומנט רגיש להקשר לפי מיקום לקסיקלי: בתוך sub הוא מכוון ל־@_, מחוצה לו הוא מכוון ל־@ARGV. הזזת שורת קוד בין התחומים האלה משנה בשקט איזה מערך הוא משנה.מערכים קשורים:
shiftקורא למתודהSHIFTעל העצם הקשור אם אחת מוגדרת; אחרת הוא חוזר ל־FETCHעל אלמנט0, ואזDELETE, ואז רצף של צמדיFETCH/STOREכדי להזיז את האלמנטים הנותרים למטה, ואזSTORESIZE. מטפלSHIFTמותאם אישית כמעט תמיד שווה לכתוב לצורך ביצועים.הפניות למערך:
shift @$arefו־shift @{ $expr }שניהם עובדים.shift $aref(ללא ה־sigil@) הייתה תכונה ניסיונית שהוספה ב־Perl 5.14 והוסרה ב־5.24 - זוהי שגיאת תחביר בגרסת Perl ש־pperl מכוון אליה.shiftהוא צרכן־lvalue, לא lvalue: לא ניתן להציב לתוצאה שלshiftכדי לשנות את המערך. השתמשו ב־spliceאו בהשמה ישירה לאינדקס לשם כך.ערך החזרה בהקשר רשימה:
shiftתמיד מחזיר סקלר בודד. השמת תוצאתו לרשימה -my ($x) = shift @arr- עובדת רק מכיוון שהסקלר הבודד ממלא את חריץ הרשימה הראשון; שאר החריצים הםundef. השתמשו ב־spliceכדי להסיר מספר אלמנטים בבת אחת.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
pop- הסרה והחזרה של האלמנט האחרון; O(1), הבחירה הנכונה כשסדר FIFO אינו דרושpush- צירוף לזנב; משולב עםshiftלהוות תור FIFOunshift- הוספה לראש; ההפוך שלshift, וגם O(n) מאותה סיבהsplice- הסרה, הוספה או החלפה של כל ריצה רציפה של אלמנטים; הכלי הכללי כאשרshift/pop/unshift/pushאינם מספיקים@ARGV- מערך ברירת המחדל ש־shiftצורך בתחום הקובץ@_- מערך ברירת המחדל ש־shiftצורך בתוך sub; מחזיק את רשימת הארגומנטים של הקורא