البحث في الموقع
المحتوى عن 'case'.
-
تعتبر العبارات الشرطية في البرنامج من الأمور الأساسيّة في البرمجة كما هو معلوم. تمتلك لغة سي شارب نوعين من العبارات الشرطية وهما: بنية if-else وبنية switch-case. العبارة الشرطية if-else وهي بنية مألوفة في معظم لغات البرمجة، تشبه هذه البنية في تشكيلها تلك الموجودة في لغات أخرى مثل ++C و Java. تمتلك هذه البنية ثلاثة أشكال سنتحدّث عنها تباعًا. الشكل الأول لبنية if الشكل الأبسط لبنية if هي: if ([condition]) { statement1; statement2; ... } إذا كان تقييم evaluate الشرط [condition] يعطينا true (أي تحقّق الشرط) عندها ستُفّذ العبارات البرمجيّة الموجودة ضمن الحاضنة {}، وإلّا (أي لم يتحقّق الشرط) فلن يُنفّذ أيّ منها. أنشئ مشروعًا جديدًا سمّه Lesson03_1 واستبدل محتويات الملف Program.cs بالبرنامج البسيط التالي الذي يعمل على مقارنة القيمة المدخلة من المستخدم مع العدد 5 ويُظهر الخرج المناسب: 1 using System; 2 3 namespace Lesson03_1 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 double x; 10 string str_x; 11 12 Console.Write("Input a number: "); 13 str_x = Console.ReadLine(); 14 15 x = double.Parse(str_x); 16 17 if(x > 5) 18 { 19 Console.WriteLine("The value {0} is greater than 5", x); 20 } 21 22 Console.WriteLine("Goodbye!"); 23 } 24 } 25 } جرّب تنفيذ هذا البرنامج باستخدام Ctrl+F5 (أو من القائمة Debug > Start Without Debugging). سيطلب منك البرنامج إدخال قيمة عدديّة، أدخل العدد 6، سيعرض البرنامج الخرج التالي: The value 6 is greater than 5 Goodbye! أعد تنفيذ البرنامج وأدخل هذه المرّة القيمة 3 لتحصل على الخرج التالي: Goodbye! لاحظ بأنّ خرج البرنامج قد اختلف باختلاف القيم المدخلة، أي أنّ هناك اختلاف في العبارات البرمجيّة التي تمّ تنفيذها في كلّ مرّة. يعود سبب ذلك إلى البنية if الموجودة بين السطرين 17 و 20. يختبر الشرط الموجود بعد كلمة if في السطر 17 فيما إذا كانت قيمة المتغيّر x أكبر تمامًا من 5. فإذا كانت نتيجة تقييم التعبير x > 5 تساوي true فهذا يعني أنّ الشرط قد تحقّق وبالتالي تنفّذ جميع العبارات البرمجيّة الموجودة في الحاضنة (بين السطرين 18 و 20). أمّا إذا كانت نتيجة تقييم التعبير x > 5 تساوي false فعندها سيتجاوز تنفيذ البرنامج البنية if إلى العبارات التي تأتي بعد السطر 20. الشكل الثاني لبنية if هذا الشكل للعبارة الشرطية if مفيد أيضًا، ويُستخدم عندما نريد الاختيار بين مجموعتين من العبارات البرمجيّة، والشكل العام له: if ([condition]) { statement1; statement2; ... } else { Statement3; Statement4; ... } لقد أضفنا القسم else مع حاضنته. المنطق هنا بسيط يمكننا قراءته بالشكل التالي: "إذا تحقق الشرط [condition] عندها تنفّذ الحاضنة الموجودة بعد if مباشرةً، وإلّا يتم تنفيذ الحاضنة الموجودة بعد else مباشرةً" لكي نتعرّف على كيفيّة التعامل مع هذا الشكل، أنشئ مشروعًا جديدًا سمّه Lesson03_2 وانسخ الشيفرة التالية إلى الملف Program.cs: 1 using System; 2 3 namespace Lesson03_2 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 double x; 10 string str_x; 11 12 Console.Write("Input a number: "); 13 str_x = Console.ReadLine(); 14 15 x = double.Parse(str_x); 16 17 if (x > 5) 18 { 19 Console.WriteLine("The value {0} is greater than 5", x); 20 } 21 else 22 { 23 Console.WriteLine("The value {0} is smaller than or equals 5", x); 24 } 25 26 Console.WriteLine("Goodbye!"); 27 } 28 } 29 } هذا البرنامج مطابق للبرنامج الذي رأيناه قبل قليل باستثناء القسم else مع حاضنته. يسلك هذا البرنامج نفس السلوك الذي يسلكه البرنامج السابق باستثناء أنّه لو أدخل المستخدم قيمة مثل 3 سيعمل البرنامج على طباعة الخرج التالي: The value 3 is smaller than or equals 5 Goodbye! لاحظ أنّ البرنامج Lesson03_1 كان يطبع العبارة !Goodbye فقط عند إدخال القيمة 3. السبب في ظهور الخرج الجديد هو وجود القسم else في بنية if السابقة، فعندما يُقيّم الشرط x > 5 في السطر 17 وتكون نتيجة تقييمه false سينتقل البرنامج فورًا إلى تنفيذ العبارات البرمجيّة الموجودة ضمن حاضنة else وهذا هو سبب ظهور هذا الخرج. العيب الوحيد في هذا البرنامج أنّه لا يستطيع التمييز بين الحالة التي تكون فيها القيمة المدخلة تساوي 5 وبين الحالة التي تكون فيها أصغر تمامًا من 5، ففي كلّ من هاتين الحالتين يعرض البرنامج نفس الخرج عن طريق تنفيذ العبارة الموجودة في السطر 23. ملاحظة: في حال كانت أيّة حاضنة تحوي عبارة برمجيّة واحد فقط، فعندها يمكن عدم استخدام قوسي الحاضنة {} مع أنّني أفضّل استخدامهما لجعل البرنامج أكثر وضوحًا. الشكل الثالث لبنية if وهو الشكل الأكثر شمولًا وفيه نستخدم القسم else if على الصورة التالية: if ([condition]) { statement1; statement2; ... } else if ([condition1]) { Statement3; Statement4; ... } else if ([condition2]) { Statement3; Statement4; ... } ... else { Statement3; Statement4; ... } يمكننا قراءة المنطق هنا على الشكل التالي: "إذا تحقّق الشرط [condition] عندها تنفّذ الحاضنة الموجودة بعد if مباشرةً، وإلّا إذا (else if) تحقّق الشرط [condition1] يتم تنفيذ الحاضنة الموجودة بعد else if الأولى مباشرةً، وإلّا إذا تحقّق الشرط [condition2] يتم تنفيذ الحاضنة الموجودة بعد else if الثانية مباشرةً، وإلّا (else) يتم تنفيذ الحاضنة الموجودة بعد else مباشرةً" نلاحظ أنّه يمكننا استخدام أقسام else if بقدر ما نريد، ولكن يمكن استخدام قسم else وحيد. ونلاحظ أيضًا أنّه بالنتيجة ستنفّذ مجموعة واحدة فقط ضمن حاضنة ما. وواضح أيضًا أنّ أقسام else if و else هي أقسام اختياريّة ووجودها غير مرتبط ببعضها، ولكن إذا حوت بنية if قسم else if فيجب أي يكون القسم else (في حال وجوده) هو القسم الأخير. لكي نثبّت هذا المفهوم بشكل جيّد انظر البرنامج Lesson03_3 التالي: 1 using System; 2 3 namespace Lesson03_3 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 double x; 10 string str_x; 11 12 Console.Write("Input a number: "); 13 str_x = Console.ReadLine(); 14 15 x = double.Parse(str_x); 16 17 if (x > 5) 18 { 19 Console.WriteLine("The value {0} is greater than 5", x); 20 } 21 else if (x == 5) 22 { 23 Console.WriteLine("The value {0} is equals 5", x); 24 } 25 else 26 { 27 Console.WriteLine("The value {0} is smaller than 5", x); 28 } 29 30 Console.WriteLine("Goodbye!"); 31 } 32 } 33 } يشبه هذا البرنامج سابقيه إلى حدٍّ بعيد، فهو يقارن القيمة المدخلة مع العدد 5 ويعرض رسالة مناسبة نتيجة عملية المقارنة. الشيء الجديد هنا هو التمييز بين الحالة التي تكون فيها القيمة المدخلة تساوي العدد 5 والحالة التي تكون فيها أصغر من العدد 5. قمنا بذلك من خلال إضافة القسم else if جديد يختبر حالة المساواة مع العدد 5. الآن أصبح منطق البرنامج كالتالي: "إذا كانت القيمة المدخلة أكبر تمامًا من 5 (السطر 17) عندها تُنفّذ العبارة الموجودة في السطر 19، وإلّا إذا كانت القيمة المدخلة تساوي 5 (السطر 21) عندها تُنفّذ العبارة الموجودة في السطر 23، وإلّا ستكون القيمة المدخلة أصغر من 5 حتمًا، وتُنفَّذ العبارة الموجودة في السطر 27." العبارة الشرطية switch-case تفيد هذه البنية في الاختيار من بين عدّة حالات منفصلة. لهذه البنية الشكل العام التالي: switch(expression) { case [A]: [statements] break; case [B]: [statements] break; ... [default:] [statements] break; } القسم الأخير default هو قسم اختياري، كما يجب أن يكون هناك قسم case واحد على الأقل. إليك الآن البرنامج Lesson03_4 لفهم كيفيّة استخدام هذه البنية: 1 using System; 2 3 namespace Lesson03_4 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 double x, y; 10 string str_x, str_y, operation; 11 12 Console.Write("Input first number: "); 13 str_x = Console.ReadLine(); 14 15 Console.Write("Input second number: "); 16 str_y = Console.ReadLine(); 17 18 Console.Write("Choose operation (+, -, *, /): "); 19 operation = Console.ReadLine(); 20 21 x = double.Parse(str_x); 22 y = double.Parse(str_y); 23 24 switch (operation) 25 { 26 case "+": 27 Console.WriteLine("{0} + {1} = {2}", x, y, x + y); 28 break; 29 case "-": 30 Console.WriteLine("{0} - {1} = {2}", x, y, x - y); 31 break; 32 case "*": 33 Console.WriteLine("{0} * {1} = {2}", x, y, x * y); 34 break; 35 case "/": 36 Console.WriteLine("{0} / {1} = {2}", x, y, x / y); 37 break; 38 default: 39 Console.WriteLine("Unsupported operation."); 40 break; 41 } 42 } 43 } 44 } البرنامج السابق عبارة عن برنامج آلة حاسبة بسيطة تدعم العمليات الحسابية الأربع: الجمع والطرح والضرب والقسمة. يطلب البرنامج من المستخدم إدخال قيمتين عدديّتين، بعد ذلك يطلب اختيار العمليّة الحسابيّة المراد إجراؤها على هاتين القيمتين (+ ، - ، * ، /) وتخزين العمليّة المختارة ضمن المتغيّر النصّي operation وذلك في السطر 19. تعمل البنية switch في السطر 24 على مقارنة قيمة المتغيّر النصيّ operation مع القيم الموجودة في أقسام case (الأسطر 26 و 29 و 32 و 35) فإذا طابقت القيمة الموجودة في operation إحدى تلك القيم، فإنّ العبارات البرمجيّة الموجودة ضمن هذا القسم سيتمّ تنفيذها. أمّا إذا لم يحدث مثل هذا التطابق، فستنفّذ العبارات البرمجيّة الموجودة في القسم الاختياري default والتي ستخبر المستخدم (في هذا المثال) بأنّ العمليّة الحسابيّة التي يرغبها لا يدعمها البرنامج. نستفيد من القسم default في تنفيذ عبارات برمجيّة في حال لم يحدث التطابق مع أيّ قسم case سابق. كما نلاحظ أنّ العبارة break الموجودة في كلّ قسم من أقسام case بالإضافة إلى قسم default هي عبارة ضرورية وتؤدّي إلى انتقال تنفيذ البرنامج إلى خارج بنية switch أي إلى السطر 42. جرّب تنفيذ البرنامج وإدخال قيم متنوّعة بالإضافة إلى تجريب العمليات الحسابيّة الأربع. جرّب إدخال عامل باقي القسمة مثلًا (%) وانظر كيف سيجيب البرنامج بالرسالة Unsupported operation. تمارين داعمة تمرين 1 في البرنامج Lesson03_4 السابق إذا أدخل المستخدم القيمة 0 للعدد الثاني، ثم اختار عمليّة القسمة ( / ) سيؤدّي ذلك إلى القسمة على صفر، وهذا يسبّب خطًأ أثناء التنفيذ runtime error يؤدّي إلى رمي استثناء وتوقّف البرنامج عن العمل. أجرِ تعديلًا على البرنامج ليأخذ هذا الأمر بالحسبان. (تلميح: أضف شرط if ضمن قسم case الموافق للعمليّة ( / ) لاختبار قيمة المتغيّر y فيما إذا كانت تساوي الصفر أم لا). تمرين 2 اكتب برنامجًا يطلب من المستخدم إدخال درجة الحرارة الحاليّة. فإذا كانت درجة الحرارة أقل من 4 مئوية يعرض البرنامج الرسالة "Very Cold". أمّا إذا كانت درجة الحرارة بين 4 وأقل من 10 مئويّة يعرض الرسالة "Cold". وفي حال كانت درجة الحرارة بين 10 وأقل من 30 مئويّة يعرض الرسالة "Normal". أمّا إذا كانت درجة الحرارة 30 فما فوق فيعرض البرنامج الرسالة "Hot". الخلاصة تعلّمنا في هذا الدرس مبادئ التعامل مع العبارات الشرطية والحاجة الماسّة إليها في اتخاذ القرارات المناسبة في البرنامج. تعرّفنا على العبارة الشرطية if-else وأشكالها المفيدة، كما تعرّفنا أيضًا على بنية الاختيار swicth-case. في مجال البرمجة من غير الممكن في الواقع أن يخلو أيّ برنامج فعليّ من وجود عبارة شرطية if واحدة على الأقل.
-
تعلمنا في الجزء الأول من بُنى التحكم عن الأمر if وكيف يُستخدم لتعديل مسار تنفيذ البرنامج بناءً على حالة خروج أحد الأوامر. يسمى هذا النوع من مسارات تنفيذ البرامج -وفق الاصطلاحات البرمجية- بالتفرّع (branching) لأنَّه يشبه كثيرًا التنقل في شجرة، فعندما تصل إلى تفرّع، فستُحدِّد نتيجة الشرط أيَّ فرعٍ ستذهب إليه. هنالك نوعٌ آخرٌ أكثر تعقيدًا من أنواع التفرع يُسمى case، وهنالك عدِّة خيارات في case، فعلى عكس التفرّع البسيط الذي فيه طريقان فقط، يمكن أن تكون هنالك عدِّة نواتج بناءً على تحقيق شرط معيّن لقيمةٍ ما. يمكنك بناء مثل هذا النوع من أنواع التفرّع باستخدام عدِّة جمل if شرطية. سنحاول في المثال الآتي التحقق من مدخلات المستخدم: #!/bin/bash echo -n "Enter a number between 1 and 3 inclusive > " read character if [ "$character" = "1" ]; then echo "You entered one." elif [ "$character" = "2" ]; then echo "You entered two." elif [ "$character" = "3" ]; then echo "You entered three." else echo "You did not enter a number between 1 and 3." fi لكن ما سبق ليس كفؤًا كما كنا نتوقع، ولكن لحسن الحظ، توفِّر الصَدَفة لنا حلًا أفضل لهذه المشكلة: الأمر المُضمَّن case، الذي يمكن استخدامه لبناء برنامج مكافئ تمامًا للبرنامج السابق: #!/bin/bash echo -n "Enter a number between 1 and 3 inclusive > " read character case $character in 1 ) echo "You entered one." ;; 2 ) echo "You entered two." ;; 3 ) echo "You entered three." ;; * ) echo "You did not enter a number between 1 and 3." esac الشكل العام للأمر case: case word in patterns ) commands ;; esac يُنفِّذ الأمر case عباراتٍ برمجيةً معيّنة إذا طابَقت الكلمة نمطًا (pattern)، يمكنك وضع أي عدد من الأنماط والعبارات. ويمكن أن تكون الأنماط نصًا عاديًا أو "محارف بديلة" (wildcards). يمكن وضع أكثر من نمط في نفس السطر بفصل الأنماط بمحرف |. هذا مثالٌ متقدمٌ يشرح لك ما أعنيه بكلامي السابق: #!/bin/bash echo -n "Type a digit or a letter > " read character case $character in # Check for letters [[:lower:]] | [[:upper:]] ) echo "You typed the letter $character" ;; # Check for digits [0-9] ) echo "You typed the digit $character" ;; # Check for anything else * ) echo "You did not type a letter or a digit" esac لاحظ النمط الخاص * الذي سيُطابِق أي شيء، لذلك سنحتاج إليه لمطابقة الحالات التي لم تُطابِقها الأنماط التي تسبقه. من المستحسن تضمين هذا النمط في نهاية الأمر case لكي يُستخدَم لكشف المدخلات غير الصحيحة. حلقات التكرار آخر جزء من بُنى التحكم التي سنناقشها هي حلقات التكرار، تُنفِّذ حلقات التكرار قسمًا من البرنامج لعددٍ من المرات وذلك بناءً على حالة خروج أحد الأوامر. توفِّر الصَدَفة ثلاثة أوامر للتكرار: while و until و for، وسنشرح while و until في هذا الدرس وسنترك for لدرسٍ لاحق. يؤدي الأمر while إلى تنفيذ كتلة من الشيفرة مرارًا وتكرارًا لطالما كانت حالة خروج الأمر المُحدَّد true (أي حالة الخروج 0). هذا مثالٌ بسيطٌ يعد الأرقام من 0 إلى 9: #!/bin/bash number=0 while [ "$number" -lt 10 ]; do echo "Number = $number" number=$((number + 1)) done أنشأنا في السطر الثالث متغيرًا وأسميناه number وأسندنا القيمة 0 إليه، ثم بدأنا حلقة while. وكما لاحظت، كان الأمر التي ستختبر حلقة while حالة خروجه هو الأمر test الذي يختبر قيمة العدد number. وفي مثالنا السابق، اختبرنا إذا كانت قيمة number أصغر من 10. لاحظ الكلمة do في السطر الرابع والكلمة done في السطر السابق. هاتان الكلمتان تحيطان بالشيفرة التي ستُكرَّر لطالما كانت حالة خروج الأمر المُحدَّد مساويةً للصفر. في غالبية الحالات، تقوم الشيفرة التي ستُكرَّر بشيءٍ ما سيؤدي في نهاية المطاف إلى تغيير حالة خروج الأمر المُحدَّد، وإلا فستكون لديك حلقة تكرار لا نهائية؛ أي حلقةُ تكرارٍ لا يتوقف تنفيذها أبدًا. تطبع الشيفرة التي ستُكرَّر في المثال السابق قيمة المتغير number (الأمر echo في السطر الخامس)، ثم تُزيد قيمة number بمقدار 1 في السطر السادس. وفي كل مرة يكتمل فيها تنفيذ الشيفرة، فسيتم التحقق من قيمة حالة الخروج للأمر test، وبعد التكرار العاشر للحلقة، فسيزداد المتغير number عشر مرات وسينتهي الأمر test بحالة خروج لا تساوي الصفر. وفي هذه المرحلة، سيُكمِل البرنامج مساره بتنفيذ التعليمات البرمجية التي تلي الكلمة done، لكن ولمّا كانت done هي آخر كلمة في مثالنا، فسينتهي تنفيذ البرنامج فورًا. يعمل الأمر until بشكلٍ مماثل، عدا أنَّ الشيفرة ستُكرَّر لطالما كانت حالة خروج الأمر المُحدَّد false (أي ليست 0). لاحظ تغيير التعبير الذي مررناه للأمر test لكي يعمل بشكلٍ مماثل للمثال السابق عن حلقة while: #!/bin/bash number=0 until [ "$number" -ge 10 ]; do echo "Number = $number" number=$((number + 1)) done بناء قائمة طريقة شائعة لتوفير واجهة للمستخدم للبرامج النصيّة (أي التي تعمل من سطر الأوامر) هي استخدام القوائم. القائمة هي سلسلة من الخيارات التي يستطيع المستخدم انتقاء واحدة منها. سنستخدم ما تعلمناه سابقًا عن الحلقات وعبارة case لبناء برنامج بسيط فيه قائمة: #!/bin/bash selection= until [ "$selection" = "0" ]; do echo " PROGRAM MENU 1 - Display free disk space 2 - Display free memory 0 - exit program " echo -n "Enter selection: " read selection echo "" case $selection in 1 ) df ;; 2 ) free ;; 0 ) exit ;; * ) echo "Please enter 1, 2, or 0" esac done الغرض من حلقة until هو إعادة عرض القائمة في كل مرة يتم اختيار عنصر من القائمة فيها. ستتكرر الحلقة إلى أن يختار المستخدم 0 (خيار الخروج). لاحظ ماذا سنفعل إذا لم تكن مدخلات المستخدم صحيحة (1 أو 2 أو 0). نستطيع إضافة دالة تطلب من المستخدم الضغط على الزر Enter بعد عرض كل خيار لتحسين طريقة عرض البرنامج عند تشغيله، وذلك بمسح الشاشة قبل إعادة عرض القائمة مرةً أخرى. هذا هو المثال المُحسَّن: #!/bin/bash press_enter() { echo -en "\nPress Enter to continue" read clear } selection= until [ "$selection" = "0" ]; do echo " PROGRAM MENU 1 - display free disk space 2 - display free memory 0 - exit program " echo -n "Enter selection: " read selection echo "" case $selection in 1 ) df ; press_enter ;; 2 ) free ; press_enter ;; 0 ) exit ;; * ) echo "Please enter 1, 2, or 0"; press_enter esac done عندما "يُعلِّق" حاسوبك … لقد مررنا جميعًا بتجربة "تعليق" أحد البرامج، الذي يحدث عندما يتوقف البرنامج عن العمل ولا يستجيب لأي شيء. ربما تظن أنَّ البرنامج قد توقف، إلا أنَّه -في معظم الحالات- ما يزال يعمل لكن واجهته مشكلةٌ في البنية المنطقية فيه وقد دخل في حلقة تكرار لا نهائية. تخيل هذه الحالة: لنقل أنَّك وصلت جهازًا خارجيًا إلى حاسوبك، مثل قرص USB، لكنك نسيت تشغيله. ثم حاولت استخدام الجهاز لكن التطبيق علّق، فعندما يحدث ذلك، تستطيع أن تتخيل المحادثة الآتية بين التطبيق والمنفذ الذي يتصل عبره الجهاز: وسيستمر الأمر هكذا إلى ما لا نهاية … البرامج المكتوبة بطريقة جيدة تتفادى الحالة السابقة بضبط مهلة زمنية (timeout)، وهذا يعني أنَّ حلقة التكرار تحسب عدد المحاولات أو تحسب مقدار الزمن الذي انتظرته لكي يحدث شيءٌ مُحدَّد. وإن تجاوز عدد المحاولات أو الزمن المُنتَظَر حدًّا معيّنًا، فسينتهي تنفيذ الحلقة وسيولِّد البرنامج رسالة خطأ. ترجمة -وبتصرّف- للمقال Flow Control - Part 2 لصاحبه William Shotts.
-
سنتعرّف في هذا الدّرس على العبارات الشرطيّة وكيفيّة استخدامها لتنفيذ أوامر أو تجاهلها استنادًا إلى شرط معيّن. افتح ملفّ روبي جديد وسمّه logic.rb أو أيّ اسم آخر مع التأكّد من كتابة rb. في آخر اسم الملفّ واكتب الشيفرات البرمجيّة التّالية والتي تمثّل نسخة مجرّدة من لعبة إلقاء النّرد: number = rand(1..6) puts "You rolled #{number}" ماذا فعلنا هنا؟ أنشأنا متغيّرًا وحفظنا به قيمة عشوائيّة بين 1 و 6، ثمّ استعملنا هذا المتغيّر لطباعة القيمة العشوائيّة على الشّاشة باستخدام أمر puts مخبرين المستخدم أنّ ناتج إلقائه للنرد هو ذلك الرقم العشوائي النّاتج عن استخدام دالّة rand (التي سبق وأن اطّلعنا عليها في الدّرس السّابق). سنتعرّف الآن على بعض العبارات الشرطيّة التي يمكننا استخدامها لإخراج بعض المعلومات عن الرقم استنادًا إلى ما إذا كان الشّرط متحقّقًا أم لا. اكتب السطر التّالي أسفل الشيفرات البرمجيّة السّابقة: puts "You rolled the highest number possible" if number == 6 تلاحظ في العبارة الشرطيّة السّابقة أنّ الشرط هو أن يكون المتغيّر number يساوي 6. إذا تحقّق هذا الشرط سنقوم بإخراج رسالة "You rolled the highest number possible". الأمر المهم لدينا هنا هو عبارة if التي تأتي قبل الشّرط الذي يجب أن يكون صحيحًا من أجل طباعة السّلسلة، في حالتنا هذه كما ذكرنا فالشّرط هو أن يكون المتغيّر مساويًا لـ 6. لاحظ كيف استخدمنا علامتي == لاختبار المساواة بين الطرفين. يختلف هذا عمّا فعلنا في بداية الشيفرات حيث استخدمنا علامة مساواة واحدة لتعيين قيمة للمتغيّر. إذًا فنستخدم علامة يساوي واحدة لتعيين القيم وعلامتين من أجل اختبار إذا كان طرفين متساويين أم لا. يمكننا أيضًا استخدام بنية مشابهة لذلك لمعرفة إذا كان الشّرط غير متحقّق كالتّالي: puts "You didn't roll the lowest number possible" if number != 1 كما تلاحظ فالجملة مشابهة إلى حدٍّ كبير، نريد طباعة هذه السلسلة إذا كان المتغيّر number لا يساوي (!=) 1. سيتم طباعة تلك السلسلة فقط عن تحقّق هذا الشرط. في الحالتين السّابقتين لدينا الجملة الشّرطيّة موجودة بالنهاية والشيفرة البرمجيّة التي نريدها أن تنفّذ موجودة في البداية. يمكننا كتابة ذلك بترتيب مختلف بأن نضع الجملة الشّرطيّة في البداية كالتّالي: if number < 5 then puts "You rolled a number less than 5" end كما تلاحظ، نحن نخبر روبي إذا كان قيمة المتغيّر أقل من 5 يجب تنفيذ الأمر الموجود بعد الكلمة المفتاحيّة then. وبالنّهاية نضع end والتي نحتاج إليها لإخبار روبي بأنّ عبارة if قد انتهت. كتابة أكثر من شرط يمكننا أيضًا كتابة أكثر من شرط في أكثر من سطر. مثال على ذلك: if number.even? puts "You rolled and even number" else puts "You rolled an odd number" end السّطر الأوّل يتحقّق إذا كان المتغيّر number عددًا زوجيًّا باستخدام دالّة even، إذا كانت الإجابة true سيتمّ تنفيذ أمر puts الخاصّ بهذا الشرط. إذا كانت قيمة المتغيّر عددًا غير زوجي، فمن البديهي أنه سيكون فرديًّا. إذًا فإنّ else تعدّ بمثابة ما نريد تنفيذه إذا لم يتحقّق الشرط. لاحظ أنّه يجب وضع end مرّة واحدة في النهاية تمامًا وليس بعد if مرّة وبعد else مرّة. elsif يمكننا كتابة عدد أكبر من الجمل الشرطيّة أيضًا باستخدام elsif. if number == 1 then puts "You rolled one" elsif number == 2 then puts "You rolled two" elsif number == 3 then puts "You rolled three" else puts "You rolled a number bigger than three" end لدينا في هذا المثال ثلاثة جمل شرطيّة مختلفة متبوعة بجملة else والتي ستُنفّذ إذا لم يتحقّق أيّ شرط من الشّروط الثلاثة السّابقة لها. لنبدأ مع أول سطر، جملة if عاديّة تتحقّق إذا كانت قيمة المتغيّر number تساوي 1، إذا كان الجواب نعم فستنفّذ روبي الأمر الموجود بعد then وتستبعد باقي الجمل الشرطيّة. أمّا إذا لم تتحقّق الجملة الشرطيّة الأولى فتنتقل روبي إلى السطر التّالي والذي يحتوي على جملة شرطيّة أخرى والتي تختبرها روبي فقط إذا لم تتحقّق الجملة الشرطيّة السّابقة، لذلك فهي تسمّى elsif. تعمل تمامًا elsif عمل if، الفرق فقط هو أنّها لا تنفّذ في حالة تحقّق الجملة الشرطيّة السّابقة لها. السطر الثالث مشابه للسطر الثّاني. وبالنهاية لدينا else والتي لا تحتوي على شرط محدّد وإنّما تنفّذ في حال عدم تحقّق أي جملة شرطيّة من الثلاث. ثم end. عبارة Case يمكننا استخدام عدد لا نهائي من جمل if, elsif, else ولكن مع زيادى عدد الشروط المطلوبة قد يصبح الأمر متعبًا ومستهلكًا للوقت. لذلك فهناك عبارة أخرى يمكننا استخدامها وهي case. حاول تخمين ما تفعله case بالاطّلاع على الشيفرات التالية: case number when 4 then puts "You rolled four" when 5 then puts "You rolled five" when 6 then puts "You rolled six" else puts "You rolled a number less than four" end كما تلاحظ، فهي تعمل بشكل مشابه جدًّا للمثال السّابق. الفرق أنّنا نستخدم case بدلاً من if. لاحظ أنّنا نضع بالبداية المتغيّر number حيث أنّ كل الجمل الشّرطيّة الموجودة بـ case تشير إلى هذا المتغيّر. على سبيل المثال بالنّظر إلى السطر الثاني، فهو يشير أنّه عندما (when) تكون قيمة المتغيّر number تساوي 4 إذًا (then) ننفّذ أمر puts. وهكذا حتى الوصول إلى else ثم end في نهاية عبارة case واللذان يستخدمان تمامًا مثل استخدامهما في عبارة if. سلسلة عبارات if يمكننا أيضًا وضع جمل if كمتسلسلات كما ترى أدناه: if number == 2 or number == 3 or number == 5 puts "You rolled a prime number" end استخدمنا جملة if عاديّة ونخبر روبي بأنّه إذا كانت قيمة المتغيّر number تساوي 2، أو (or) تساوي 3، أو (or) تساوي 4 فكما قد تكون توقّعت سيتمّ تنفيذ الأمر الخاصّ بتلك العبارة. إذًا فنحن في الواقع نختبر ثلاث شروط مختلفة وإذا تحقّق شرط واحد منها فإنّ ناتج هذه العبارة الشّرطيّة سيصبح true. هناك طريقة أخرى لكتابة تلك الشيفرات. puts "You rolled a square number" if number == 1 || number == 4 يسمّى || برمز الأنبوب المزدوج (Double Pipe Symbol) والذي يمثّل كلمة or. لاحظ أيضًا كيف قمنا بعكس الجملة الشرطيّة وذلك بوضع الشرط في النهاية كما فعلنا سابقًا. هناك أيضًا عبارة and والتي تتحقّق إذا تحقّقت جميع الشروط الموجودة والتي مربوط بينها باستخدام and. if number.odd? and number >= 4 puts "You rolled five" end في الشيفرات البرمجيّة أعلاه نتحقّق إذا كانت قيمة المتغيّر هي عدد فردي و (and) أكبر من أو تساوي 4. هذا الرّمز >= يعني أنّ الطرف الأيسر من الجملة أكبر من أو يساوي الطرف الأيمن. بالرجوع مجدّدًا إلى الشيفرة البرمجيّة السّابقة فإنّه عند تحقّق الشرطين معًا (وليس أحدهما فقط) فسيتمّ تنفيذ الأمر puts الذي يلي العبارة الشرطيّة. مثل or، هناك أيضًا طريقة أخرى لكتابة and. if number.even? && number <= 3 puts "You rolled two" end الشيفرة أعلاه مشابهة تمامًا للسّابقة، نتحقّق إذا كانت قيمة المتغيّر عددًا زوجيًّا و (&&) أقل من أو تساوي 3. إذا تحقّق الشّرطيّن المربوط بينها باستخدام && فسيتمّ تنفيذ أمر puts الخاصّ بالعبارة الشرطيّة. رمز && يسمّى Double Ampersand Symbol. ختام تعرّفنا في هذا الدّرس على العبارات الشرطيّة في ruby وكيفيّة استخدامها. إذا كتبت الشيفرة البرمجيّة المستخدمة في هذا الدّرس في ملفّ روبي فعلاً فجرّب تنفيذها في سطر أوامر روبي التفاعليّ كما تعلّمنا في الدّروس السّابقة وقارن النتائج بالشيفرات الموجودة لمعرف وظيفة كل جزء منها.