אופרטורי טווח ו־flip-flop#
שני אופרטורים עם שני תפקידים שונים לחלוטין בהתאם להקשר: בהקשר רשימה הם מייצרים טווחים, ובהקשר סקלר הם ביטויים בוליאניים ״flip-flop״ עם מצב להתאמת טווחי שורות בעיבוד זרמים.
אופרטור | תפקיד בהקשר רשימה | תפקיד בהקשר סקלר |
|---|---|---|
| טווח כולל | flip-flop (כניסה בבדיקת־שקר) |
| טווח כולל | flip-flop (כניסה בבדיקת־אמת) |
.. בהקשר רשימה - טווחים#
בהקשר רשימה, .. מייצר את הסדרה הכוללת בין נקודות הקצה שלו:
0..9 # (0,1,2,3,4,5,6,7,8,9)
'a'..'z' # ('a','b',...,'y','z') 26 elements
'aa'..'zz' # ('aa','ab',...,'zy','zz') 676 elements
'A'..'F' # ('A','B','C','D','E','F')
for my $i (1..100) { ... } # numeric for-loop
for my $name ('alpha'..'omega') { ... } # alphabetic, magic-incremented
עבור נקודות קצה מספריות התוצאה היא סדרת המספרים השלמים (עם סדר קפדני - 5..1 הוא הרשימה הריקה, לעולם לא הפוך). עבור נקודות קצה מחרוזתיות נעשה שימוש בהגדלה־הקסומה מ־++, שמעניקה לכם את הפריסה האלפביתית הטבעית (ועל 'aa' עד 'zz' את 676 הצירופים בני שתי האותיות הצפויים).
ניב Perl נפוץ:
my @hex = ('0'..'9', 'a'..'f'); # 16 hex digits as strings
my @rev = reverse 1..10; # (10,9,8,...,1)
@arr[ 5..9 ] # array slice, indexes 5..9
@arr[ -3..-1 ] # last three elements
טווח כל־השלמים יכול להיות גדול מאוד - 1..1_000_000_000 הוא רשימה בת מיליארד אלמנטים. Perl 5 מייצר טווחי לולאה בעצלתיים ב־for, כך ש־for my $i (1..1_000_000_000) בטוח, אך my @x = 1..1_000_000_000 מקצה את המערך כולו. PetaPerl פועל לפי אותו כלל.
נקודות קצה הפוכות#
5..1 ריק. אין צורת ״טווח הפוך״; אם אתם רוצים סדר יורד, ייצרו סדר עולה ובצעו reverse:
1..5 # (1,2,3,4,5)
5..1 # () - empty, no warning
reverse 1..5 # (5,4,3,2,1)
נקודות קצה מטיפוסים מעורבים#
אם אחת מנקודות הקצה נראית מספרית, .. מבצע טווח מספרי:
'1'..'5' # (1,2,3,4,5) - numeric
'1'..'10' # (1,2,3,4,5,6,7,8,9,10) - numeric
'a'..'5' # ('a') - magic-increment from "a",
# stops because it can't reach "5"
הפכו את הטיפוס למפורש כדי להימנע מבלבול:
0+'1' .. 0+'5' # numeric, no doubt
sprintf("%d", 1) .. sprintf("%d", 5)
בפועל, כתבו טווחי מספרים שלמים עם ליטרלים שלמים חשופים וטווחי תווים עם אותיות מחרוזת־מצוטטת חשופות; ההבחנה בין קסם־לבין־אריתמטיקה נובעת אוטומטית.
.. ו־... בהקשר סקלר - flip-flops#
בתוך הקשר בוליאני (if, while, ?:, הצד הימני של &&/||///), .. הופך לביטוי בעל מצב שזוכר אם הוא כרגע בין התאמה בצד שמאל לבין התאמה בצד ימין.
while (<$fh>) {
if (/^BEGIN/ .. /^END/) { # true from BEGIN line through END line
print; # print everything in between, inclusive
}
}
הסמנטיקה:
ה־flip-flop הוא בתחילה שקר.
כשתנאי השמאל (
/^BEGIN/) הופך לאמת, ה־flip-flop עובר לאמת, והצד הימני מוערך מיד באותה איטרציה.ה־flip-flop נשאר אמת באיטרציות הבאות עד שתנאי הימין (
/^END/) הופך לאמת. באיטרציה ההיא הוא מחזיר אמת ואז עובר חזרה לשקר.כך ששורת ה־BEGIN ושורת ה־END שתיהן נכללות.
כשה־flip-flop הוא אמת, הוא מחזיר מספר סידורי (1 באיטרציית הכניסה, 2 בבאה, …). באיטרציה הסוגרת הוא מחזיר את הספירה ולאחריה E0 - כך שהערך הוא אמת (מחרוזת לא־ריקה, לא ה־"0" השקרי) אך מומר למחרוזת כמספר 0 לשם בהירות קוסמטית. בדרך כלל תוכלו להתייחס אליו כבוליאני רגיל.
... נבדל מ־.. בפרט אחד:
..(שתי נקודות) - כשהצד השמאלי הופך לאמת, הצד הימני נבדק באותה איטרציה. כך שאותה שורה יכולה לפתוח ולסגור את הטווח....(שלוש נקודות) - כשהצד השמאלי הופך לאמת, הצד הימני אינו נבדק עד האיטרציה הבאה. תמיד טווח רב־שורתי.
while (<$fh>) {
print if /<head>/ .. /<\/head>/; # one-line <head>...</head> works
print if /<head>/ ... /<\/head>/; # forces multi-line; same-line ignored
}
מתי תשתמשו ב־flip-flop#
ה־flip-flop זוהר בסינון טווחי־שורות בסגנון awk - שליפת קטעים מקובץ יומן, בידוד בלוק קוד תחום מ־markdown, עיבוד בלוק תצורה התחום במילות מפתח. הוא ידוע כלא־אהוב על מבקרי קוד מפני שה־statefulness שלו מובלע.
שתי חלופות מעשיות שחלקם מעדיפים:
# Explicit state variable - equivalent semantics, easier to grep for:
my $in_block = 0;
while (<$fh>) {
$in_block = 1 if /^BEGIN/;
print if $in_block;
$in_block = 0 if /^END/;
}
# A simple two-step iterator:
while (<$fh>) {
if (/^BEGIN/ .. /^END/) { print }
}
ה־flip-flop מנצח בתמציתיות; הצורה המפורשת מנצחת בבהירות במחיר של שלוש שורות נוספות. בחרו לפי הקהל.
ראו גם#
reverse,grep,map- אופרטורי רשימה הנכתבים בדרך כלל בצירוף עם טווחים.מציין־מקום - פרוסות מערך
@arr[1..3]מסתמכות על טווח־בהקשר־רשימה.קדימות -
..ו־...יושבים בשורה 17, בין||///ל־?:. כמעט תמיד הקיפו בסוגריים בעת שילוב עם לוגיקה.