الفرق بين المراجعتين لصفحة: «Ruby/control expressions»
ط تصحيح تنسيق الأكواد |
جميل-بيلوني (نقاش | مساهمات) |
||
(3 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:تعابير التحكم في روبي}}</noinclude> | |||
لدى لغة روبي العديد من الطرق للتحكم في مسار | [[تصنيف: Ruby]] | ||
الاختبارات الشرطيّة في بنى | [[تصنيف: Ruby Syntax]] | ||
== بنية If | لدى لغة روبي العديد من الطرق للتحكم في مسار تنفيذ البرنامج، وكل البنى المذكورة هنا تعيد قيمةً. | ||
أبسط أشكال بنية if الشرطيّة يحتوي على جزأين، الاختبار الشّرطي، والجزء التّنفيذي then. | |||
هذه بنية if بسيطة: | في الاختبارات الشرطيّة في بنى التحكّم، تعدّ القيمة <code>nil</code> و <code>false</code> على أنّها قيم خطأ، بينما تُعدُّ القيمة <code>true</code> وأيّ كائن آخر على أنه قيم صحيحة. وفي هذا التوثيق، سنستخدم <code>true</code> للتعبير عن القيم الصحيحة و <code>false</code> للتعبير عن القيم الخطأ. | ||
<syntaxhighlight lang="ruby"> | ==بنية <code>If</code> الشرطية== | ||
أبسط أشكال بنية <code>if</code> الشرطيّة يحتوي على جزأين، الاختبار الشّرطي، والجزء التّنفيذي <code>then</code>. هذه بنية <code>if</code> بسيطة:<syntaxhighlight lang="ruby"> | |||
if true then | if true then | ||
puts "the test resulted in a true-value" | puts "the test resulted in a true-value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>وتكون النتيجة طباعة الناتج التالي: <syntaxhighlight lang="text"> | ||
وتكون النتيجة طباعة: | |||
<syntaxhighlight lang="text"> | |||
“the test resulted in a true-value” | “the test resulted in a true-value” | ||
</syntaxhighlight> | </syntaxhighlight>كلمة <code>then</code> اختياريّة:<syntaxhighlight lang="ruby"> | ||
كلمة then اختياريّة: | |||
<syntaxhighlight lang="ruby"> | |||
if true | if true | ||
puts "the test resulted in a true-value" | puts "the test resulted in a true-value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>في هذا التّوثيق، سنحذف <code>then</code> الاختياريّة في كلّ البنى، وهذا هو الاستخدام الأكثر شيوعًا للبنية <code>if</code>. | ||
في | |||
بإمكانك ايضًا إضافة بنية else والتي ستنفّذ عندما لا يساوي الشرط الاختباريّ قيمة true: | بإمكانك ايضًا إضافة بنية <code>else</code> والتي ستنفّذ عندما لا يساوي الشرط الاختباريّ قيمة <code>true</code>:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
if false | if false | ||
puts "the test resulted in a true-value" | puts "the test resulted in a true-value" | ||
سطر 28: | سطر 24: | ||
puts "the test resulted in a false-value" | puts "the test resulted in a false-value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>وستكون النتيجة طباعة: <syntaxhighlight lang="text"> | ||
وستكون النتيجة طباعة: | |||
<syntaxhighlight lang="text"> | |||
“the test resulted in a false-value” | “the test resulted in a false-value” | ||
</syntaxhighlight> | </syntaxhighlight>كما يمكنك أن تضيف أيّ عدد من الاختبارات الإضافيّة لبنية <code>if</code> باستخدام <code>elsif</code>. وكلّ شرط في <code>elsif</code> ينفّذ طالما كانت جميع الاختبارات السابقة له مساويةً إلى <code>false</code>:<syntaxhighlight lang="ruby"> | ||
كما يمكنك أن تضيف أيّ عدد من الاختبارات الإضافيّة لبنية if باستخدام elsif. وكلّ شرط في elsif ينفّذ طالما كانت جميع الاختبارات السابقة له مساويةً إلى false: | |||
<syntaxhighlight lang="ruby"> | |||
a = 1 | a = 1 | ||
if a == 0 | if a == 0 | ||
سطر 43: | سطر 35: | ||
puts "a is some other value" | puts "a is some other value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>وتكون النتيجة “a is one” وذلك لأنّ 1 لا يساوي 0، و <code>else</code> تنفّذ فقط عندما لا يوجد ايّ اختبار محقّق فوقها. | ||
وتكون النتيجة “a is one” وذلك لأنّ 1 لا يساوي 0، و else تنفّذ فقط عندما لا يوجد ايّ اختبار محقّق فوقها. | |||
بمجرّد أن يتحقّق أيّ اختبار سواء في if أو في elsif تعدّ بنية if قد اكتملت ولن | بمجرّد أن يتحقّق أيّ اختبار سواء في <code>if</code> أو في <code>elsif</code>، تعدّ بنية <code>if</code> قد اكتملت ولن تُجرَى أيّة اختبارات أخرى. وكما هو الحال بالنّسبة للبنية <code>if</code>، يمكن للبنية <code>elsif</code> أن تتبعها <code>then</code>. | ||
في المثال التالي ستكون النتيجة طباعة "a is one" فقط: | |||
<syntaxhighlight lang="ruby"> | في المثال التالي ستكون النتيجة طباعة "a is one" فقط:<syntaxhighlight lang="ruby"> | ||
a = 1 | a = 1 | ||
if a == 0 | if a == 0 | ||
سطر 58: | سطر 50: | ||
puts "a is some other value" | puts "a is some other value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>الاختبارات الشرطيّة الخاصّة بالبنية <code>if</code> و <code>elsif</code> قد يكون لها تأثيرات جانبيّة، والحالة الأكثر شيوعًا هي الاحتفاظ بقيمة لمتغيّر محليّ:<syntaxhighlight lang="ruby"> | ||
الاختبارات الشرطيّة الخاصّة بالبنية if و elsif قد يكون لها تأثيرات جانبيّة، والحالة الأكثر شيوعًا هي الاحتفاظ بقيمة لمتغيّر محليّ: | |||
<syntaxhighlight lang="ruby"> | |||
if a = object.some_value | if a = object.some_value | ||
# do something to a | # do something to a | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>القيمة النّاتجة لبنية <code>if</code> هي آخر قيمة تنفّذ في هذه البنية. | ||
القيمة النّاتجة لبنية if هي آخر قيمة تنفّذ في هذه البنية. | ==تعبير <code>if</code> الثلاثي== | ||
== تعبير if الثلاثي == | يمكنك أيضًا كتابة بنية <code>if-then-else</code> باستخدام <code>?</code> و <code>:</code> وهي ما تسمى بتعبير <code>if</code> الثلاثي:<syntaxhighlight lang="ruby"> | ||
يمكنك أيضًا كتابة بنية if-then-else باستخدام ? و : وهي ما تسمى بتعبير if الثلاثي: | input_type = gets =~ /hello/i ? "greeting" : "other" | ||
input_type = gets =~ /hello/i ? "greeting" : "other" | </syntaxhighlight>وهي تكافئ البنية التالية:<syntaxhighlight lang="ruby"> | ||
وهي تكافئ | |||
<syntaxhighlight lang="ruby"> | |||
input_type = | input_type = | ||
if gets =~ /hello/i | if gets =~ /hello/i | ||
سطر 77: | سطر 65: | ||
"other" | "other" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>رغم أنّ تعبير <code>if</code> الثلاثيّ مختصر أكثر من الشكل الاعتيادي للبنية إلا أنّه من المفضّل لسهولة القراءة فلا يستخدم إلا للاختبارات البسيطة. تجنب أيضًا أن تُدخل أكثر من ثلاثيّ شرطي في نفس البنية كي لا يصبح الأمر مربكًا. | ||
رغم أنّ تعبير if الثلاثيّ مختصر أكثر من الشكل الاعتيادي للبنية إلا أنّه من المفضّل لسهولة القراءة | ==بنية <code>unless</code>== | ||
== بنية unless == | بنية <code>unless</code> هي النقيض لبنية <code>if</code> إذ أنّ الكتلة البرمجيّة فيها تنفّذ عندما يحقّق الاختبار الشرطيّ قيمة <code>false</code>:<syntaxhighlight lang="ruby"> | ||
بنية unless هي النقيض لبنية if إذ أنّ الكتلة البرمجيّة فيها تنفّذ عندما يحقّق الاختبار الشرطيّ قيمة false: | |||
<syntaxhighlight lang="ruby"> | |||
unless true | unless true | ||
puts "the value is a false-value" | puts "the value is a false-value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>ولا شيء يطبع هنا إذ أنّ <code>true</code> لا تساوي القيمة <code>false</code> (أو أي قيمة خطأ). يمكنك أيضًا الاستغناء عن <code>then</code> أو كتابتها كما هو الحال في <code>if</code>. | ||
ولا شيء يطبع هنا إذ أنّ true لا تساوي قيمة خطأ | |||
يمكنك أيضًا الاستغناء عن then أو كتابتها كما هو الحال في if. | لاحظ أنّ بنية <code>unless</code> الأخيرة تكافئ تمامًا:<syntaxhighlight lang="ruby"> | ||
لاحظ أنّ بنية unless | |||
<syntaxhighlight lang="ruby"> | |||
if not true | if not true | ||
puts "the value is a false-value" | puts "the value is a false-value" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>كما بإمكانك استخدام <code>else</code> أيضًا مع <code>unless</code>:<syntaxhighlight lang="ruby"> | ||
كما بإمكانك استخدام else أيضًا مع unless: | |||
<syntaxhighlight lang="ruby"> | |||
unless true | unless true | ||
puts "the value is false" | puts "the value is false" | ||
سطر 101: | سطر 83: | ||
puts "the value is true" | puts "the value is true" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>وتكون النتيجة طباعة “the value is true” من <code>else</code>. | ||
وتكون النتيجة طباعة “the value is true” من else | |||
ليس بإمكانك استخدام elsif مع بنية unless. | ليس بإمكانك استخدام <code>elsif</code> مع بنية <code>unless</code>. | ||
القيمة الناتجة عن بنية unless هي آخر قيمة تم تنفيذها في هذه البنية. | |||
If و unless المعدِّلتان | القيمة الناتجة عن بنية <code>unless</code> هي آخر قيمة تم تنفيذها في هذه البنية. | ||
يمكن استخدام if و unless أيضًا لتعديل تعبير برمجيّ، وحينها يصبح الجزء الأيسر هو الجزء التنفيذي then والجزء الأيمن هو الاختبار الشرطيّ: | |||
<syntaxhighlight lang="ruby"> | == البنيتان <code>If</code> و <code>unless</code> المعدِّلتان == | ||
يمكن استخدام <code>if</code> و <code>unless</code> أيضًا لتعديل تعبير برمجيّ، وحينها يصبح الجزء الأيسر هو الجزء التنفيذي <code>then</code> والجزء الأيمن هو الاختبار الشرطيّ:<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
a += 1 if a.zero? | a += 1 if a.zero? | ||
p a | p a | ||
</syntaxhighlight> | </syntaxhighlight>هذا يطبع 1.<syntaxhighlight lang="ruby"> | ||
هذا يطبع 1. | |||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
a += 1 unless a.zero? | a += 1 unless a.zero? | ||
p a | p a | ||
</syntaxhighlight> | </syntaxhighlight>هذا يطبع 0. | ||
هذا يطبع 0. | |||
صحيح أنّ if المعدِّلة والعاديّة لهما شرط اختباريّ وجزء تنفيذيّ، إلا أنّهما ليسا متطابقين على وجه الدّقة وذلك بسبب اختلاف ترتيب كلّ منهما في مفسّر اللغة. هذا المثال يوضّح الفرق: | صحيح أنّ <code>if</code> المعدِّلة والعاديّة لهما شرط اختباريّ وجزء تنفيذيّ، إلا أنّهما ليسا متطابقين على وجه الدّقة وذلك بسبب اختلاف ترتيب كلّ منهما في مفسّر اللغة. هذا المثال يوضّح الفرق:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
p a if a = 0.zero? | p a if a = 0.zero? | ||
</syntaxhighlight> | </syntaxhighlight>هذا سيسبّب ظهور الخطأ: <code>[[Ruby/NameError|NameError]]</code> مع الرسالة “undefined local variable or method `a'” | ||
هذا سيسبّب ظهور الخطأ: NameError “undefined local variable or method `a'” | |||
عندما يحلّل مفسّر اللغة هذا التعبير فإنّه يصادف بداية a ويعدّه استدعاء لتابع ضمن كتلة | عندما يحلّل مفسّر اللغة هذا التعبير فإنّه يصادف بداية <code>a</code> ويعدّه استدعاء لتابع ضمن كتلة <code>then</code>، ولاحقًا يرى الإسناد إلى <code>a</code> في الشرط الاختباريّ ويعدّه متغيّرًا محليًّا. | ||
يبدأ تنفيذ هذا السّطر بتنفيذ الشّرط الاختباريّ a=0.zero | |||
ذات الحالة تنطبق على unless. | يبدأ تنفيذ هذا السّطر بتنفيذ الشّرط الاختباريّ <code>?a=0.zero</code>، وبما أنّ الشّرط محقّق سينتقل التنفيذ إلى الكتلة <code>then</code> وفيها <code>p a</code>. ولمَّا كان a مسجلًا على أنَّه تابعٌ وهذا التابع غير موجود، فسيُطلق الخطأ <code>[[Ruby/NameError|NameError]]</code>. | ||
== بنية case == | |||
يمكن استخدام بنية case | ذات الحالة تنطبق على <code>unless</code>. | ||
الاستخدام الشائع لها أن | ==بنية <code>case</code> == | ||
هذا مثال عن استخدام case | يمكن استخدام بنية <code>case</code> بطريقتين؛ الاستخدام الشائع لها أن توازن كائنًا ما مقابل أنماط مختلفة، وتتمّ المطابقة مع هذه الأنماط باستخدام تابع <code>+===+</code> والذي يقابله تابع <code>+==+</code> من الصنف <code>[[Ruby/Object|Object]]</code>. أما الأصناف الأخرى فعليها أن تعيد تعريف التابع ليأخذ سلوكًا ذا معنى. انظر [[Ruby/Module/3D-3D-3D|<code>Module.===</code>]] و <code>[[Ruby/Regexp/case equality|Regexp.===]]</code> للحصول على أمثلة عملية. | ||
<syntaxhighlight lang="ruby"> | |||
هذا مثال عن استخدام <code>case</code> لموازنة [[Ruby/String|سلسلة نصية]] (string) مع [[Ruby/Regexp|نمط]]:<syntaxhighlight lang="ruby"> | |||
case "12345" | case "12345" | ||
when /^1/ | when /^1/ | ||
سطر 138: | سطر 119: | ||
puts "I don't know what the string starts with" | puts "I don't know what the string starts with" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>هنا توازن [[Ruby/String|السلسلة النصية]] "12345" مع [[Ruby/Regexp|النمط]] /1^/ وذلك باستدعاء /^1/ === "12345" والذي يعيد القيمة <code>true</code>. وكما هو الحال في بنية <code>if</code>، تنفّذ الكتلة البرمجيّة التابعة لأوّل اختبار شرطيّ يتحقّق، وكل الحالات الأخرى تُتجاهل. وفي حال عدم وجود أي نمط مطابق، تُنفّذ الكتلة <code>else</code>. | ||
هنا | |||
كلّ من else و then اختياريّين، بنية case التالية تعطي نفس النتيجة للبنية السابقة: | كلّ من <code>else</code> و <code>then</code> اختياريّين، بنية <code>case</code> التالية تعطي نفس النتيجة للبنية السابقة:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
case "12345" | case "12345" | ||
when /^1/ | when /^1/ | ||
puts "the string starts with one" | puts "the string starts with one" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>كما بإمكانك إدراج أكثر من شرط اختباريّ معًا ضمن <code>when</code>:<syntaxhighlight lang="ruby"> | ||
كما بإمكانك إدراج أكثر من شرط اختباريّ معًا ضمن when: | |||
<syntaxhighlight lang="ruby"> | |||
case "2" | case "2" | ||
when /^1/, "2" | when /^1/, "2" | ||
puts "the string starts with one or is '2'" | puts "the string starts with one or is '2'" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>سيجرّب مفسّر روبي كل شرط على حدة وفق الترتيب، إذ بدايةً يختبر <code>/^1/ === "2"</code> والذي يُرجع <code>false</code>، ثمّ يختبر <code>"2" === "2"</code> والذي يعيد <code>true</code>، فيطبع الناتج التالي في النّهاية:<syntaxhighlight lang="text"> | ||
سيجرّب مفسّر | “the string starts with one or is '2'” | ||
بإمكانك كتابة then على نفس السطر بعد شرط when مباشرة، عادة ما يُستخدم هذا الأسلوب لكتابة كتلة then على نفس السّطر مع الشرط الخاصّ بها: | </syntaxhighlight>بإمكانك كتابة <code>then</code> على نفس السطر بعد شرط <code>when</code> مباشرة، عادة ما يُستخدم هذا الأسلوب لكتابة كتلة <code>then</code> على نفس السّطر مع الشرط الخاصّ بها:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
case a | case a | ||
when 1, 2 then puts "a is one or two | when 1, 2 then puts "a is one or two | ||
سطر 162: | سطر 139: | ||
else puts "I don't know what a is" | else puts "I don't know what a is" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>الطريقة الثانية لكتابة بنية <code>case</code> تشابه بنية <code>if-elsif</code>:<syntaxhighlight lang="ruby"> | ||
الطريقة الثانية لكتابة بنية case تشابه بنية if-elsif: | |||
<syntaxhighlight lang="ruby"> | |||
a = 2 | a = 2 | ||
case | case | ||
سطر 174: | سطر 149: | ||
puts "I don't know what a is" | puts "I don't know what a is" | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>وبالمثل، كل من <code>then</code> و <code>else</code> اختياريّتين. | ||
وبالمثل، كل من then و else اختياريّتين. | |||
القيمة الناتجة عن بنية case هي آخر قيمة تُنفّذ في البنية. | القيمة الناتجة عن بنية <code>case</code> هي آخر قيمة تُنفّذ في البنية. | ||
== حلقة while | ==حلقة <code>while</code> التكرارية== | ||
تُنفّذ حلقة while التكراريّة طالما أنّ شرطها محقّق: | تُنفّذ حلقة <code>while</code> التكراريّة طالما أنّ شرطها محقّق:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
while a < 10 do | while a < 10 do | ||
سطر 186: | سطر 160: | ||
end | end | ||
p a | p a | ||
</syntaxhighlight> | </syntaxhighlight>هذا يطبع الأرقام من 0 إلى 10، فالشرط <code>a<10</code> يُختبَر قبل دخول كل حلقة ومن ثمّ ينفّذ ما بداخلها، ومن ثمّ يختبر الشرط مجدّدًا. وعندما تكون نتيجة الاختبار <code>false</code>، يتوقف تنفيذ الحلقة التّكرارية. | ||
هذا يطبع الأرقام من 0 إلى 10، فالشرط a<10 يُختبَر قبل دخول كل حلقة ومن ثمّ ينفّذ ما بداخلها، ومن ثمّ يختبر الشرط مجدّدًا. وعندما تكون نتيجة الاختبار false يتوقف تنفيذ الحلقة التّكرارية. | |||
الكلمة المحجوزة do اختياريّة، فالحلقة التالية مكافئة للحلقة السابقة: | الكلمة المحجوزة <code>do</code> اختياريّة، فالحلقة التالية مكافئة للحلقة السابقة:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
while a < 10 | while a < 10 | ||
p a | p a | ||
a += 1 | a += 1 | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>نتيجة حلقة <code>while</code> التكرارية تساوي <code>nil</code> إلا إذا استٌخدمت الكلمة المحجوزة <code>break</code> لتزوّدها بقيمة عند الخروج منها. | ||
نتيجة حلقة while التكرارية تساوي nil إلا إذا استٌخدمت break لتزوّدها بقيمة. | ==حلقة <code>until</code> التكرارية== | ||
== حلقة until التكرارية == | تنفّذ هذه الحلقة طالما أنّ شرطها غير محقّق:<syntaxhighlight lang="ruby"> | ||
تنفّذ هذه الحلقة طالما أنّ شرطها غير محقّق: | |||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
until a > 10 do | until a > 10 do | ||
سطر 205: | سطر 176: | ||
end | end | ||
p a | p a | ||
</syntaxhighlight> | </syntaxhighlight>هذا يطبع الأرقام من 0 إلى 11. وكما هو الحال في <code>while</code> فالشرط <code>a>10</code> يُختبر في كلّ مرة قبل دخول الحلقة، ومن ثمّ يٌنفّذ محتواها. إذا كان الشّرط غير محقق، فستستمرّ الحلقة بالتكرار. | ||
هذا يطبع الأرقام من 0 إلى 11. وكما هو الحال في while فالشرط a>10 يُختبر في كلّ مرة قبل دخول الحلقة، ومن ثمّ يٌنفّذ | |||
وكما هو الحال في while فإنّ كلمة do اختياريّة. وكذلك القيمة الناتجة من الحلقة تبقى nil إلا إذا استخدمت break. | وكما هو الحال في <code>while</code>، فإنّ كلمة <code>do</code> اختياريّة. وكذلك القيمة الناتجة من الحلقة تبقى <code>nil</code> إلا إذا استخدمت الكلمة <code>break</code>. | ||
== حلقة for التكرارية == | ==حلقة <code>for</code> التكرارية== | ||
حلقة for التكرارية تتكون من for | حلقة <code>for</code> التكرارية تتكون من <code>for</code> متبوعةً بمتغيّر سيحتوي معامل التّكرار (iteration argument) ومن ثمّ كلمة <code>in</code> ثم القيم التي ستكرّر الحلقة وفقها. أمّا <code>do</code> فهي اختياريّة:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
for value in [1, 2, 3] do | for value in [1, 2, 3] do | ||
puts value | puts value | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>يطبع 1 ثمّ 2 ثمّ 3 إن استخدام <code>for</code> مشابه لاستخدام <code>each</code> إلّا أنّ الأولى لا تٌنشئ نطاقًا جديدًا للمتغيّرات. | ||
يطبع 1 ثمّ 2 ثمّ | |||
نتيجة حلقة <code>for</code> التكراريّة هي آخر قيمة تصل إليها في التّكرار، إلا إذا استُخدمت الكلمة <code>break</code> لمقاطعة الحلقة والخروج منها. | |||
نتيجة حلقة for التكراريّة هي آخر قيمة تصل إليها في التّكرار، إلا إذا استُخدمت break. | |||
نادرًا ما تُستخدم حلقة for في البرامج الحديثة المكتوبة بلغة روبي. | نادرًا ما تُستخدم حلقة <code>for</code> في البرامج الحديثة المكتوبة بلغة روبي. | ||
== | ==البنيتان <code>while</code> و <code>until</code> المعدِّلتان== | ||
كما هو الحال في if و | كما هو الحال في البنيتان <code>if</code> و <code>unless</code> المعدلتان، يمكن لحلقة <code>while</code> و <code>until</code> أن تكونا معدِّلتين:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
a += 1 while a < 10 | a += 1 while a < 10 | ||
p a # تطبع 10 | p a # تطبع 10 | ||
استخدام | |||
# كمعدّلة until استخدام | |||
a = 0 | a = 0 | ||
a += 1 until a > 10 | a += 1 until a > 10 | ||
p a # تطبع 11 | p a # تطبع 11 | ||
</syntaxhighlight> | </syntaxhighlight>يمكنك استخدام <code>begin</code> و <code>end</code> مع حلقة <code>while</code> لتنفّذ محتوى الحلقة مرة واحدة قبل اختبار الشرط.<syntaxhighlight lang="ruby"> | ||
يمكنك استخدام begin و end مع حلقة while لتنفّذ محتوى الحلقة مرة واحدة قبل اختبار الشرط. | |||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
begin | begin | ||
سطر 237: | سطر 205: | ||
end while a < 10 | end while a < 10 | ||
p a # تطبع 10 | p a # تطبع 10 | ||
</syntaxhighlight> | </syntaxhighlight>إذا لم تستخدم أيًا من <code>rescue</code> أو <code>ensure</code>، فستعمل لغة روبي على تحسين أيّة شيفرة تعامل مع الاستثناءات تمرّ عليها. | ||
إذا لم تستخدم أيًا من rescue أو ensure | ==الكلمة <code>break</code> المحجوزة== | ||
== | استخدم الكلمة <code>break</code> لمغادرة كتلة برمجيّة في وقت مبكر. في هذا المثال يتوقّف التكّرار على بقيّة العناصر في <code>values</code> إذا كان أحدها زوجيًّا:<syntaxhighlight lang="ruby"> | ||
استخدم break لمغادرة كتلة برمجيّة في وقت مبكر. في هذا المثال يتوقّف التكّرار على بقيّة العناصر في values إذا كان أحدها | |||
<syntaxhighlight lang="ruby"> | |||
values.each do |value| | values.each do |value| | ||
break if value.even? | break if value.even? | ||
# ... | # ... | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight>يمكنك أيضًا أن توقف تنفيذ حلقة <code>while</code> باستخدام <code>break</code>:<syntaxhighlight lang="ruby"> | ||
يمكنك أيضًا أن توقف تنفيذ حلقة while باستخدام break: | |||
<syntaxhighlight lang="ruby"> | |||
a = 0 | a = 0 | ||
while true do | while true do | ||
سطر 256: | سطر 220: | ||
end | end | ||
p a | p a | ||
</syntaxhighlight> | </syntaxhighlight>هذا يطبع العددين 0 و 1 فقط. | ||
هذا يطبع | |||
تقبل break أن تمرّر لها قيمة تعيدها كنتيجة للبنية التي تقوم بإيقافها: | تقبل <code>break</code> أن تمرّر لها قيمة تعيدها كنتيجة للبنية التي تقوم بإيقافها:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
result = [1, 2, 3].each do |value| | result = [1, 2, 3].each do |value| | ||
break value * 2 if value.even? | break value * 2 if value.even? | ||
سطر 265: | سطر 228: | ||
p result # تطبع 4 | p result # تطبع 4 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | ==الكلمة <code>next</code> المحجوزة== | ||
استخدم next لتتخطى ما تبقّى من الجولة الحاليّة في التكرار: | استخدم الكلمة <code>next</code> لتتخطى ما تبقّى من الجولة الحاليّة في التكرار:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
result = [1, 2, 3].map do |value| | result = [1, 2, 3].map do |value| | ||
next if value.even? | next if value.even? | ||
سطر 273: | سطر 235: | ||
end | end | ||
p result # تطبع [2, nil, 6] | p result # تطبع [2, nil, 6] | ||
</syntaxhighlight> | </syntaxhighlight>تقبل <code>next</code> أن تمرّر لها معاملًا تُرجعه كنتيجة للجولة الحاليّة من الحلقة التّكرارية:<syntaxhighlight lang="ruby"> | ||
تقبل next أن تمرّر لها معاملًا تُرجعه كنتيجة للجولة الحاليّة من الحلقة التّكرارية: | |||
<syntaxhighlight lang="ruby"> | |||
result = [1, 2, 3].map do |value| | result = [1, 2, 3].map do |value| | ||
next value if value.even? | next value if value.even? | ||
سطر 282: | سطر 242: | ||
p result # نطبع [2, 2, 6] | p result # نطبع [2, 2, 6] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | ==الكلمة <code>redo</code> المحجوزة== | ||
استخدم | استخدم الكلمة <code>redo</code> لإعادة تنفيذ الجولة الحاليّة:<syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
result = [] | result = [] | ||
while result.length < 10 do | while result.length < 10 do | ||
سطر 292: | سطر 251: | ||
end | end | ||
p result | p result | ||
</syntaxhighlight> | </syntaxhighlight>هذا المثال يطبع: [0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11] | ||
هذا المثال يطبع: [0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11] | |||
في الإصدار 1.8 من لغة | في الإصدار 1.8 من لغة روبي، كان بإمكانك أن تستخدم <code>retry</code> في نفس الأماكن التي تستخدم فيها <code>redo</code>. لم يعد هذا متاحًا الآن، فاستخدام <code>retry</code> خارج كتلة <code>rescue</code> سيطلق الخطأ <code>[[Ruby/SyntaxError|SyntaxError]]</code>. انظر الصفحة الخاصة [[Ruby/exceptions|بالاستثناءات]] لتعرف أكثر عن الاستخدام الصحيح للكلمة <code>retry</code>. | ||
== القلاب (Flip-Flop) | ==القلاب== | ||
القلّاب (Flip-Flop) هو بنية تحكّم نادر الوجود والاستعمال؛ يكمن استخدامه الأساسي في معالجة النّصوص في برامج روبي ذات السّطر الواحد والمستخدمة بواسطة <code>ruby -n</code> أو <code>ruby -p</code>. | |||
صيغة القلّاب هي كالتالي، بداية الشّرط الذي يعبّر عن دخول القلاب حالة التفعيل (on) ومن ثمّ نقطتين متتاليتين (..) أو ثلاثة نقاط (...)، ومن ثمّ الشرط الذي يعبّر عن انتقال القلّاب إلى حالة عدم التفعيل (off). وطالما أنّ القلّاب في حالة تفعيل فسيستمرّ بإعطاء | |||
إليك مثالًا: | صيغة القلّاب هي كالتالي، بداية الشّرط الذي يعبّر عن دخول القلاب حالة التفعيل (on) ومن ثمّ نقطتين متتاليتين (..) أو ثلاثة نقاط (...)، ومن ثمّ الشرط الذي يعبّر عن انتقال القلّاب إلى حالة عدم التفعيل (off). وطالما أنّ القلّاب في حالة تفعيل فسيستمرّ بإعطاء القيمة <code>true</code>، وإذا كان غير مفعلّ يعطي <code>false</code>. | ||
<syntaxhighlight lang="ruby"> | |||
إليك مثالًا عن بنية القلاب:<syntaxhighlight lang="ruby"> | |||
selected = [] | selected = [] | ||
0.upto 10 do |value| | 0.upto 10 do |value| | ||
سطر 305: | سطر 265: | ||
end | end | ||
p selected # يطبع [2, 3, 4, 5, 6, 7, 8] | p selected # يطبع [2, 3, 4, 5, 6, 7, 8] | ||
</syntaxhighlight> | </syntaxhighlight>في المثال السابق نجد أنّ شرط التفعيل هو <code>value==2</code>. فالقلاب يكون ابتداءً في حالة عدم تفعيل لكل من القيمتين 0 و 1، لكنه يصبح مفعلًا عند 2 ويبقى كذلك حتى نصل إلى 8 وعندها "يقلب" حالته إلى off ويستمر كذلك لكل من 9 و 10. | ||
في المثال السابق نجد أنّ شرط التفعيل هو value==2. فالقلاب يكون ابتداءً في حالة عدم تفعيل لكل من القيمتين 0 و 1، لكنه يصبح مفعلًا عند 2 ويبقى كذلك حتى نصل إلى 8 وعندها "يقلب" حالته إلى off ويستمر كذلك لكل من 9 و 10. | |||
يجب أن يُستخدم القلاب في بنية شرطيّة مثل if أو while أو unless أو until أو غيرها، بما في ذلك أنواعها المعدِّلة. | يجب أن يُستخدم القلاب في بنية شرطيّة مثل <code>if</code> أو <code>while</code> أو <code>unless</code> أو <code>until</code> أو غيرها، بما في ذلك أنواعها المعدِّلة. | ||
عندما تستخدم مجالًا متضمّنًا (..)، فإنّ شرط إلغاء التفعيل يقيّم عندما يتغيّر شرط التفعيل: | |||
<syntaxhighlight lang="ruby"> | عندما تستخدم مجالًا متضمّنًا (..)، فإنّ شرط إلغاء التفعيل يقيّم عندما يتغيّر شرط التفعيل:<syntaxhighlight lang="ruby"> | ||
selected = [] | selected = [] | ||
0.upto 5 do |value| | 0.upto 5 do |value| | ||
سطر 315: | سطر 275: | ||
end | end | ||
p selected # يطبع [2] | p selected # يطبع [2] | ||
</syntaxhighlight> | </syntaxhighlight>هنا كلا جانبي القلاب يقيّمان بحيث يقلب إلى on و off فقط عندما تكون القيمة مساوية للقيمة 2. وطالما أنّ القلاب أصبح مفعلًا في هذه الجولة فسيرجع القيمة <code>true</code>. | ||
هنا كلا جانبي القلاب يقيّمان بحيث يقلب إلى on و off فقط عندما تكون القيمة مساوية للقيمة 2. وطالما أنّ القلاب أصبح مفعلًا في هذه الجولة فسيرجع | |||
أمّا عندما تستخدم | أمّا عندما تستخدم مجالًا مستبعِدًا (...) فإن شرط إلغاء التفعيل يقيّم في الجولة التالية: <syntaxhighlight lang="ruby"> | ||
<syntaxhighlight lang="ruby"> | |||
selected = [] | selected = [] | ||
0.upto 5 do |value| | 0.upto 5 do |value| | ||
سطر 324: | سطر 283: | ||
end | end | ||
p selected # يطبع [2, 3, 4, 5] | p selected # يطبع [2, 3, 4, 5] | ||
</syntaxhighlight> | </syntaxhighlight>هنا يقلب القلاب إلى وضع التفعيل عندما تكون القيمة 2، لكنّه لا يقلب إلى وضع عدم التفعيل في ذات الجولة، فالشرط الثاني سيقيّم في الجولة التالية وستكون القيمة قد تخطت 2 بالفعل، ولن تعود إليها مرّة أخرى. | ||
هنا يقلب القلاب إلى وضع التفعيل عندما تكون القيمة 2، لكنّه لا يقلب إلى وضع عدم التفعيل في ذات الجولة، فالشرط الثاني سيقيّم في الجولة التالية وستكون القيمة قد تخطت 2 بالفعل، ولن تعود إليها مرّة أخرى. | ==المصادر== | ||
== المصادر == | *[https://ruby-doc.org/core-2.5.1/doc/syntax/control_expressions_rdoc.html صفحة Control Expressions في توثيق روبي الرسمي] | ||
* [https://ruby-doc.org/core-2.5.1/doc/syntax/control_expressions_rdoc.html صفحة Control Expressions في توثيق روبي الرسمي] |
المراجعة الحالية بتاريخ 06:33، 19 نوفمبر 2018
لدى لغة روبي العديد من الطرق للتحكم في مسار تنفيذ البرنامج، وكل البنى المذكورة هنا تعيد قيمةً.
في الاختبارات الشرطيّة في بنى التحكّم، تعدّ القيمة nil
و false
على أنّها قيم خطأ، بينما تُعدُّ القيمة true
وأيّ كائن آخر على أنه قيم صحيحة. وفي هذا التوثيق، سنستخدم true
للتعبير عن القيم الصحيحة و false
للتعبير عن القيم الخطأ.
بنية If
الشرطية
أبسط أشكال بنية if
الشرطيّة يحتوي على جزأين، الاختبار الشّرطي، والجزء التّنفيذي then
. هذه بنية if
بسيطة:
if true then
puts "the test resulted in a true-value"
end
وتكون النتيجة طباعة الناتج التالي:
“the test resulted in a true-value”
كلمة then
اختياريّة:
if true
puts "the test resulted in a true-value"
end
في هذا التّوثيق، سنحذف then
الاختياريّة في كلّ البنى، وهذا هو الاستخدام الأكثر شيوعًا للبنية if
.
بإمكانك ايضًا إضافة بنية else
والتي ستنفّذ عندما لا يساوي الشرط الاختباريّ قيمة true
:
if false
puts "the test resulted in a true-value"
else
puts "the test resulted in a false-value"
end
وستكون النتيجة طباعة:
“the test resulted in a false-value”
كما يمكنك أن تضيف أيّ عدد من الاختبارات الإضافيّة لبنية if
باستخدام elsif
. وكلّ شرط في elsif
ينفّذ طالما كانت جميع الاختبارات السابقة له مساويةً إلى false
:
a = 1
if a == 0
puts "a is zero"
elsif a == 1
puts "a is one"
else
puts "a is some other value"
end
وتكون النتيجة “a is one” وذلك لأنّ 1 لا يساوي 0، و else
تنفّذ فقط عندما لا يوجد ايّ اختبار محقّق فوقها.
بمجرّد أن يتحقّق أيّ اختبار سواء في if
أو في elsif
، تعدّ بنية if
قد اكتملت ولن تُجرَى أيّة اختبارات أخرى. وكما هو الحال بالنّسبة للبنية if
، يمكن للبنية elsif
أن تتبعها then
.
في المثال التالي ستكون النتيجة طباعة "a is one" فقط:
a = 1
if a == 0
puts "a is zero"
elsif a == 1
puts "a is one"
elsif a >= 1
puts "a is greater than or equal to one"
else
puts "a is some other value"
end
الاختبارات الشرطيّة الخاصّة بالبنية if
و elsif
قد يكون لها تأثيرات جانبيّة، والحالة الأكثر شيوعًا هي الاحتفاظ بقيمة لمتغيّر محليّ:
if a = object.some_value
# do something to a
end
القيمة النّاتجة لبنية if
هي آخر قيمة تنفّذ في هذه البنية.
تعبير if
الثلاثي
يمكنك أيضًا كتابة بنية if-then-else
باستخدام ?
و :
وهي ما تسمى بتعبير if
الثلاثي:
input_type = gets =~ /hello/i ? "greeting" : "other"
وهي تكافئ البنية التالية:
input_type =
if gets =~ /hello/i
"greeting"
else
"other"
end
رغم أنّ تعبير if
الثلاثيّ مختصر أكثر من الشكل الاعتيادي للبنية إلا أنّه من المفضّل لسهولة القراءة فلا يستخدم إلا للاختبارات البسيطة. تجنب أيضًا أن تُدخل أكثر من ثلاثيّ شرطي في نفس البنية كي لا يصبح الأمر مربكًا.
بنية unless
بنية unless
هي النقيض لبنية if
إذ أنّ الكتلة البرمجيّة فيها تنفّذ عندما يحقّق الاختبار الشرطيّ قيمة false
:
unless true
puts "the value is a false-value"
end
ولا شيء يطبع هنا إذ أنّ true
لا تساوي القيمة false
(أو أي قيمة خطأ). يمكنك أيضًا الاستغناء عن then
أو كتابتها كما هو الحال في if
.
لاحظ أنّ بنية unless
الأخيرة تكافئ تمامًا:
if not true
puts "the value is a false-value"
end
كما بإمكانك استخدام else
أيضًا مع unless
:
unless true
puts "the value is false"
else
puts "the value is true"
end
وتكون النتيجة طباعة “the value is true” من else
.
ليس بإمكانك استخدام elsif
مع بنية unless
.
القيمة الناتجة عن بنية unless
هي آخر قيمة تم تنفيذها في هذه البنية.
البنيتان If
و unless
المعدِّلتان
يمكن استخدام if
و unless
أيضًا لتعديل تعبير برمجيّ، وحينها يصبح الجزء الأيسر هو الجزء التنفيذي then
والجزء الأيمن هو الاختبار الشرطيّ:
a = 0
a += 1 if a.zero?
p a
هذا يطبع 1.
a = 0
a += 1 unless a.zero?
p a
هذا يطبع 0.
صحيح أنّ if
المعدِّلة والعاديّة لهما شرط اختباريّ وجزء تنفيذيّ، إلا أنّهما ليسا متطابقين على وجه الدّقة وذلك بسبب اختلاف ترتيب كلّ منهما في مفسّر اللغة. هذا المثال يوضّح الفرق:
p a if a = 0.zero?
هذا سيسبّب ظهور الخطأ: NameError
مع الرسالة “undefined local variable or method `a'”
عندما يحلّل مفسّر اللغة هذا التعبير فإنّه يصادف بداية a
ويعدّه استدعاء لتابع ضمن كتلة then
، ولاحقًا يرى الإسناد إلى a
في الشرط الاختباريّ ويعدّه متغيّرًا محليًّا.
يبدأ تنفيذ هذا السّطر بتنفيذ الشّرط الاختباريّ ?a=0.zero
، وبما أنّ الشّرط محقّق سينتقل التنفيذ إلى الكتلة then
وفيها p a
. ولمَّا كان a مسجلًا على أنَّه تابعٌ وهذا التابع غير موجود، فسيُطلق الخطأ NameError
.
ذات الحالة تنطبق على unless
.
بنية case
يمكن استخدام بنية case
بطريقتين؛ الاستخدام الشائع لها أن توازن كائنًا ما مقابل أنماط مختلفة، وتتمّ المطابقة مع هذه الأنماط باستخدام تابع +===+
والذي يقابله تابع +==+
من الصنف Object
. أما الأصناف الأخرى فعليها أن تعيد تعريف التابع ليأخذ سلوكًا ذا معنى. انظر Module.===
و Regexp.===
للحصول على أمثلة عملية.
هذا مثال عن استخدام case
لموازنة سلسلة نصية (string) مع نمط:
case "12345"
when /^1/
puts "the string starts with one"
else
puts "I don't know what the string starts with"
end
هنا توازن السلسلة النصية "12345" مع النمط /1^/ وذلك باستدعاء /^1/ === "12345" والذي يعيد القيمة true
. وكما هو الحال في بنية if
، تنفّذ الكتلة البرمجيّة التابعة لأوّل اختبار شرطيّ يتحقّق، وكل الحالات الأخرى تُتجاهل. وفي حال عدم وجود أي نمط مطابق، تُنفّذ الكتلة else
.
كلّ من else
و then
اختياريّين، بنية case
التالية تعطي نفس النتيجة للبنية السابقة:
case "12345"
when /^1/
puts "the string starts with one"
end
كما بإمكانك إدراج أكثر من شرط اختباريّ معًا ضمن when
:
case "2"
when /^1/, "2"
puts "the string starts with one or is '2'"
end
سيجرّب مفسّر روبي كل شرط على حدة وفق الترتيب، إذ بدايةً يختبر /^1/ === "2"
والذي يُرجع false
، ثمّ يختبر "2" === "2"
والذي يعيد true
، فيطبع الناتج التالي في النّهاية:
“the string starts with one or is '2'”
بإمكانك كتابة then
على نفس السطر بعد شرط when
مباشرة، عادة ما يُستخدم هذا الأسلوب لكتابة كتلة then
على نفس السّطر مع الشرط الخاصّ بها:
case a
when 1, 2 then puts "a is one or two
when 3 then puts "a is three"
else puts "I don't know what a is"
end
الطريقة الثانية لكتابة بنية case
تشابه بنية if-elsif
:
a = 2
case
when a == 1, a == 2
puts "a is one or two"
when a == 3
puts "a is three"
else
puts "I don't know what a is"
end
وبالمثل، كل من then
و else
اختياريّتين.
القيمة الناتجة عن بنية case
هي آخر قيمة تُنفّذ في البنية.
حلقة while
التكرارية
تُنفّذ حلقة while
التكراريّة طالما أنّ شرطها محقّق:
a = 0
while a < 10 do
p a
a += 1
end
p a
هذا يطبع الأرقام من 0 إلى 10، فالشرط a<10
يُختبَر قبل دخول كل حلقة ومن ثمّ ينفّذ ما بداخلها، ومن ثمّ يختبر الشرط مجدّدًا. وعندما تكون نتيجة الاختبار false
، يتوقف تنفيذ الحلقة التّكرارية.
الكلمة المحجوزة do
اختياريّة، فالحلقة التالية مكافئة للحلقة السابقة:
while a < 10
p a
a += 1
end
نتيجة حلقة while
التكرارية تساوي nil
إلا إذا استٌخدمت الكلمة المحجوزة break
لتزوّدها بقيمة عند الخروج منها.
حلقة until
التكرارية
تنفّذ هذه الحلقة طالما أنّ شرطها غير محقّق:
a = 0
until a > 10 do
p a
a += 1
end
p a
هذا يطبع الأرقام من 0 إلى 11. وكما هو الحال في while
فالشرط a>10
يُختبر في كلّ مرة قبل دخول الحلقة، ومن ثمّ يٌنفّذ محتواها. إذا كان الشّرط غير محقق، فستستمرّ الحلقة بالتكرار.
وكما هو الحال في while
، فإنّ كلمة do
اختياريّة. وكذلك القيمة الناتجة من الحلقة تبقى nil
إلا إذا استخدمت الكلمة break
.
حلقة for
التكرارية
حلقة for
التكرارية تتكون من for
متبوعةً بمتغيّر سيحتوي معامل التّكرار (iteration argument) ومن ثمّ كلمة in
ثم القيم التي ستكرّر الحلقة وفقها. أمّا do
فهي اختياريّة:
for value in [1, 2, 3] do
puts value
end
يطبع 1 ثمّ 2 ثمّ 3 إن استخدام for
مشابه لاستخدام each
إلّا أنّ الأولى لا تٌنشئ نطاقًا جديدًا للمتغيّرات.
نتيجة حلقة for
التكراريّة هي آخر قيمة تصل إليها في التّكرار، إلا إذا استُخدمت الكلمة break
لمقاطعة الحلقة والخروج منها.
نادرًا ما تُستخدم حلقة for
في البرامج الحديثة المكتوبة بلغة روبي.
البنيتان while
و until
المعدِّلتان
كما هو الحال في البنيتان if
و unless
المعدلتان، يمكن لحلقة while
و until
أن تكونا معدِّلتين:
a = 0
a += 1 while a < 10
p a # تطبع 10
# كمعدّلة until استخدام
a = 0
a += 1 until a > 10
p a # تطبع 11
يمكنك استخدام begin
و end
مع حلقة while
لتنفّذ محتوى الحلقة مرة واحدة قبل اختبار الشرط.
a = 0
begin
a += 1
end while a < 10
p a # تطبع 10
إذا لم تستخدم أيًا من rescue
أو ensure
، فستعمل لغة روبي على تحسين أيّة شيفرة تعامل مع الاستثناءات تمرّ عليها.
الكلمة break
المحجوزة
استخدم الكلمة break
لمغادرة كتلة برمجيّة في وقت مبكر. في هذا المثال يتوقّف التكّرار على بقيّة العناصر في values
إذا كان أحدها زوجيًّا:
values.each do |value|
break if value.even?
# ...
end
يمكنك أيضًا أن توقف تنفيذ حلقة while
باستخدام break
:
a = 0
while true do
p a
a += 1
break if a < 10
end
p a
هذا يطبع العددين 0 و 1 فقط.
تقبل break
أن تمرّر لها قيمة تعيدها كنتيجة للبنية التي تقوم بإيقافها:
result = [1, 2, 3].each do |value|
break value * 2 if value.even?
end
p result # تطبع 4
الكلمة next
المحجوزة
استخدم الكلمة next
لتتخطى ما تبقّى من الجولة الحاليّة في التكرار:
result = [1, 2, 3].map do |value|
next if value.even?
value * 2
end
p result # تطبع [2, nil, 6]
تقبل next
أن تمرّر لها معاملًا تُرجعه كنتيجة للجولة الحاليّة من الحلقة التّكرارية:
result = [1, 2, 3].map do |value|
next value if value.even?
value * 2
end
p result # نطبع [2, 2, 6]
الكلمة redo
المحجوزة
استخدم الكلمة redo
لإعادة تنفيذ الجولة الحاليّة:
result = []
while result.length < 10 do
result << result.length
redo if result.last.even?
result << result.length + 1
end
p result
هذا المثال يطبع: [0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11]
في الإصدار 1.8 من لغة روبي، كان بإمكانك أن تستخدم retry
في نفس الأماكن التي تستخدم فيها redo
. لم يعد هذا متاحًا الآن، فاستخدام retry
خارج كتلة rescue
سيطلق الخطأ SyntaxError
. انظر الصفحة الخاصة بالاستثناءات لتعرف أكثر عن الاستخدام الصحيح للكلمة retry
.
القلاب
القلّاب (Flip-Flop) هو بنية تحكّم نادر الوجود والاستعمال؛ يكمن استخدامه الأساسي في معالجة النّصوص في برامج روبي ذات السّطر الواحد والمستخدمة بواسطة ruby -n
أو ruby -p
.
صيغة القلّاب هي كالتالي، بداية الشّرط الذي يعبّر عن دخول القلاب حالة التفعيل (on) ومن ثمّ نقطتين متتاليتين (..) أو ثلاثة نقاط (...)، ومن ثمّ الشرط الذي يعبّر عن انتقال القلّاب إلى حالة عدم التفعيل (off). وطالما أنّ القلّاب في حالة تفعيل فسيستمرّ بإعطاء القيمة true
، وإذا كان غير مفعلّ يعطي false
.
إليك مثالًا عن بنية القلاب:
selected = []
0.upto 10 do |value|
selected << value if value==2..value==8
end
p selected # يطبع [2, 3, 4, 5, 6, 7, 8]
في المثال السابق نجد أنّ شرط التفعيل هو value==2
. فالقلاب يكون ابتداءً في حالة عدم تفعيل لكل من القيمتين 0 و 1، لكنه يصبح مفعلًا عند 2 ويبقى كذلك حتى نصل إلى 8 وعندها "يقلب" حالته إلى off ويستمر كذلك لكل من 9 و 10.
يجب أن يُستخدم القلاب في بنية شرطيّة مثل if
أو while
أو unless
أو until
أو غيرها، بما في ذلك أنواعها المعدِّلة.
عندما تستخدم مجالًا متضمّنًا (..)، فإنّ شرط إلغاء التفعيل يقيّم عندما يتغيّر شرط التفعيل:
selected = []
0.upto 5 do |value|
selected << value if value==2..value==2
end
p selected # يطبع [2]
هنا كلا جانبي القلاب يقيّمان بحيث يقلب إلى on و off فقط عندما تكون القيمة مساوية للقيمة 2. وطالما أنّ القلاب أصبح مفعلًا في هذه الجولة فسيرجع القيمة true
.
أمّا عندما تستخدم مجالًا مستبعِدًا (...) فإن شرط إلغاء التفعيل يقيّم في الجولة التالية:
selected = []
0.upto 5 do |value|
selected << value if value==2...value==2
end
p selected # يطبع [2, 3, 4, 5]
هنا يقلب القلاب إلى وضع التفعيل عندما تكون القيمة 2، لكنّه لا يقلب إلى وضع عدم التفعيل في ذات الجولة، فالشرط الثاني سيقيّم في الجولة التالية وستكون القيمة قد تخطت 2 بالفعل، ولن تعود إليها مرّة أخرى.