רשימות

any#

מחזיר אמת אם BLOCK מניב אמת עבור לפחות איבר אחד של LIST.

any מריץ את BLOCK פעם אחת לכל איבר של LIST, יוצר alias של $_ לאיבר הנוכחי, ומחזיר ערך אמת ברגע שהבלוק מניב אמת. אם אף איבר אינו גורם לבלוק להיות אמת — לרבות המקרה שבו LIST ריקה — any מחזיר שקר. הוא לעולם לא מריץ את הבלוק יותר פעמים מהנדרש: התוצאה האמיתית הראשונה מכריעה את התשובה והאיברים הנותרים אינם נבדקים.

any אינו זמין ללא תנאי. זוהי מילת מפתח של הליבה מוגנת־תכונה שהוצגה ב־Perl 5.42; יש להפעיל אותה באמצעות:

use feature 'keyword_any';

List::Util::any הוותיק, הזמין לפחות מאז Perl 5.20, מממש את אותה סמנטיקה כתת־שגרה. השניים ניתנים להחלפה בקוד יומיומי — יש לבחור במילת המפתח של הליבה כאשר רוצים תקורת קריאה מעט נמוכה יותר ופחות frame stack אחד בפרופילים, או ב־List::Util::any כאשר נדרשים גם ייצואים אחרים של List::Util או תמיכה ב־Perl ישן מ־5.42.

תקציר#

use feature 'keyword_any';
any BLOCK LIST

מה מוחזר#

ערך בוליאני: ערך אמת אם איטרציה כלשהי של BLOCK הניבה אמת, ערך שקר אחרת. הצורה המדויקת של ערך האמת/שקר אינה מוגדרת — יש להתייחס להחזרה כבוליאני, אין להסתמך על קבלת 1 ו־"" באופן ספציפי.

LIST ריקה מחזירה שקר. זוהי התשובה המתמטית הנכונה (כמת הקיום מעל תחום ריק הוא שקר) ותואמת ל־List::Util::any.

מצב גלובלי שהפונקציה נוגעת בו#

  • $_ מקבל alias לכל איבר של LIST בתורו בזמן ש־BLOCK רץ. ה־aliasing הוא מאותו סוג ש־map ו־grep משתמשים בו: שינוי $_ בתוך הבלוק משנה את איבר הרשימה עצמו. יש להשתמש במשתנה לקסיקלי בעל שם באמצעות my $x = $_ בשורה הראשונה של הבלוק כאשר נדרש העתק בטוח.

דוגמאות#

בדיקה אם שורה כלשהי ברשימה תואמת לתבנית:

use feature 'keyword_any';
my @lines = ("foo\n", "bar ERROR baz\n", "quux\n");
if (any { /ERROR/ } @lines) {
    warn "log contains an error line\n";
}

בדיקת סף מספרי:

use feature 'keyword_any';
my @nums = (1, 4, 7, 12, 3);
print "over limit\n" if any { $_ > 10 } @nums;   # over limit

זיהוי דגל בשורת הפקודה, ללא טעינת מודול:

use feature 'keyword_any';
if (any { $_ eq '--verbose' } @ARGV) {
    $verbose = 1;
}

any ביחד עם all כבדיקת שפיות — לכל רשומה יש id, ולפחות אחת מסומנת פעילה:

use feature qw(keyword_any keyword_all);
my @records = (
    { id => 1, active => 0 },
    { id => 2, active => 1 },
);
die "malformed" unless all { defined $_->{id} } @records;
die "none active" unless any { $_->{active} } @records;

שימוש בגרסת List::Util כאשר אי אפשר להסתמך על Perl 5.42:

use List::Util qw(any);
print "found\n" if any { $_ eq 'needle' } @haystack;

מקרי קצה#

  • קצר־לוגי על התוצאה האמיתית הראשונה. תופעות לוואי ב־BLOCK רצות רק עבור איברים שנבדקו לפני (וכולל) האיבר האמיתי הראשון. אין להשתמש ב־any כדי להפעיל לולאה שחייבת לגעת בכל איבר — יש להשתמש ב־for או map לשם כך.

  • LIST ריקה מחזירה שקר. any { anything } () הוא שקר מבלי להריץ את הבלוק כלל.

  • ה־aliasing של $_ זהה ל־map ו־grep. כתיבה ל־$_ משנה את איבר רשימת המקור. הניב any { my $x = $_; ... } הופך את ההעתקה למפורשת.

  • return בתוך BLOCK חוזר מתת־השגרה העוטפת, לא מ־any. כדי לסיים את הסריקה מוקדם עם ערך אמת ספציפי, יש לאפשר לבלוק להעריך לאותו ערך — any כבר עושה קצר־לוגי.

  • מילת מפתח של הליבה לעומת List::Util::any. שניהם מממשים את אותה סמנטיקה. מילת המפתח של הליבה חוסכת frame קריאה ברמת Perl לכל הפעלה של any עצמו, שמופיע בפרופילינג צפוף; הבלוק עצמו עדיין רץ לכל איבר בשני המקרים. ערבוב שניהם באותו קובץ הוא חוקי אך מבלבל; יש לבחור אחד לכל קובץ.

  • אזהרת experimental::keyword_any. מכיוון שמילת המפתח עדיין מסומנת ניסיונית, הפעלתה פולטת אזהרה בקטגוריה experimental::keyword_any בשימוש הראשון. יש להשתיק אותה באמצעות no warnings 'experimental::keyword_any'; ברגע שהוחלט להסתמך על מילת המפתח.

הבדלים מן ה-upstream#

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

ראו גם#

  • all — המקבילה של כמת הכלל; אמת אם ורק אם BLOCK מניב אמת עבור כל איבר

  • grep — אוסף כל איבר תואם; scalar grep { ... } @list בעל אותו ערך אמת כמו any { ... } @list אך מריץ את הבלוק עבור כל איבר

  • List::Util::any — צורת תת־שגרה מלפני 5.42 עם סמנטיקה זהה

  • List::Util::first — מחזיר את האיבר הראשון שעבורו הבלוק אמיתי, במקום ערך בוליאני; יש להשתמש בזה כאשר נדרש האיבר עצמו

  • map — אותו חוזה aliasing של $_, אך תמיד מבקר בכל איבר ואוסף תוצאות