المولدات في PHP

من موسوعة حسوب
< PHP
مراجعة 04:28، 20 يناير 2018 بواسطة Mohammed Taher (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

تقدّم المولِّدات (Generators) طريقة سهلة لاستخدام المكرِّرات (Iterators) البسيطة دون الدخول في تعقيدات استخدام صنف يطبّق الواجهة Iterator.

تتيح المولِّدات كتابة شيفرة تستخدم foreach لمرور على مجموعة من البيانات دون الحاجة إلى بناء مصفوفة في الذاكرة مما قد يؤدي إلى تجاوز حدود الذاكرة، أو يحتاج إلى وقت معالجة طويل لإنشائه. بدلًا من ذلك، يمكن كتابة دالة مولِّدة وهي دالة مشابهة للدوال الاعتيادية باستثناء أنّها لا تعيد النتيجة مرة واحدة بل تعيد العدد المطلوب من النتائج لغرض تقديم القيم التي يتم المرور عليها.

ومن أبسط الأمثلة على المولِّدات هو إعادة استخدام الدالة range()‎ كمولِّد. تنشئ الدالة range()‎ الاعتيادية مصفوفة تتضمن جميع القيم وتعيدها وقد ينتج عن ذلك مصفوفة كبيرة جدًّا، فعلى سبيل المثال استدعاء الدالة range(0, 1000000)‎ يستهلك ما يقارب 100 MB من الذاكرة.

يمكن استبدال الدالة الاعتيادية بالدالة المولدة xrange()‎‎، والتي تحتاج إلى كمية مقبولة من الذاكرة لإنشاء كائن Iterator وتتبع حالة المولّد الحالية داخليًا، وكلّ ذلك يستهل أقل من 1 كيلوبايت.

المثال 1: استخدام الدالة range()‎ كدالة مولّدة

لاحظ أنّ كلتا الدالتين range()‎ و xrange()‎ تعطيان المخرجات ذاتها.

<?php
function xrange($start, $limit, $step = 1) {
    if ($start < $limit) {
        if ($step <= 0) {
            throw new LogicException('Step must be +ve');
        }

        for ($i = $start; $i <= $limit; $i += $step) {
            yield $i;
        }
    } else {
        if ($step >= 0) {
            throw new LogicException('Step must be -ve');
        }

        for ($i = $start; $i >= $limit; $i += $step) {
            yield $i;
        }
    }
}

echo 'Single digit odd numbers from range():  ';
foreach (range(1, 9, 2) as $number) {
    echo "$number ";
}
echo "\n";

echo 'Single digit odd numbers from xrange(): ';
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}
?>

يعطي المثال السابق المخرجات التالية:

Single digit odd numbers from range():  1 3 5 7 9 
Single digit odd numbers from xrange(): 1 3 5 7 9

كائنات Generator

عند استدعاء الدالة المولِّدة للمرة الأولى تعيد الدالة كائنًا من الصنف الداخلي Generator. يطبّق هذا الكائن واجهة Iterator بنفس الطريقة التي يتبعها كائن iterator الموجّه للإمام فقط، ويقدّم التوابع التي يمكن استدعاءها لمعالجة حالة المولِّد، ومنها إرسال القيم إلى المولِّد واستقبالها منه.

مصادر