الفرق بين المراجعتين ل"Ruby/control expressions"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(إضافة الترجمة الأساسية بدون تنسيق الأكود)
 
ط (تصحيح تنسيق الأكواد)
سطر 1: سطر 1:
 
= تعابير التحكّم في لغة روبي =
 
= تعابير التحكّم في لغة روبي =
 
لدى لغة روبي العديد من الطرق للتحكم في مسار التنفيذ، وكل البنى المذكورة هنا تعيد قيمة.
 
لدى لغة روبي العديد من الطرق للتحكم في مسار التنفيذ، وكل البنى المذكورة هنا تعيد قيمة.
 
 
الاختبارات الشرطيّة في بنى التحكّم تعدّ nil و false على أنّها قيمة صحيحة، بينما true وأيّ كائن آخر على أنه قيمة خاطئة. وفي هذا التوثيق سنستخدم true للتعبير عن القيم الصحيحة و false للتعبير عن الخطأ.
 
الاختبارات الشرطيّة في بنى التحكّم تعدّ nil و false على أنّها قيمة صحيحة، بينما true وأيّ كائن آخر على أنه قيمة خاطئة. وفي هذا التوثيق سنستخدم true للتعبير عن القيم الصحيحة و false للتعبير عن الخطأ.
 
 
== بنية If الشرطيّة ==
 
== بنية If الشرطيّة ==
 
أبسط أشكال بنية if الشرطيّة يحتوي على جزأين، الاختبار الشّرطي، والجزء التّنفيذي then.
 
أبسط أشكال بنية if الشرطيّة يحتوي على جزأين، الاختبار الشّرطي، والجزء التّنفيذي then.
 
 
هذه بنية if بسيطة:
 
هذه بنية if بسيطة:
 
+
<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 lang="text">
 +
“the test resulted in a true-value”
 +
</syntaxhighlight>
 
كلمة then اختياريّة:
 
كلمة 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>
 
في التّوثيق سنحذف then الاختياريّة في كلّ البنى، وهذا هو الاستخدام الأكثر شيوعًا للبنية if.
 
في التّوثيق سنحذف then الاختياريّة في كلّ البنى، وهذا هو الاستخدام الأكثر شيوعًا للبنية if.
 
 
بإمكانك ايضًا إضافة بنية else والتي ستنفّذ عندما لا يساوي الشرط الاختباريّ قيمة true:
 
بإمكانك ايضًا إضافة بنية else والتي ستنفّذ عندما لا يساوي الشرط الاختباريّ قيمة true:
 
+
<syntaxhighlight lang="ruby">
 
if false
 
if false
 
 
 puts "the test resulted in a true-value"
 
 puts "the test resulted in a true-value"
 
 
else
 
else
 
 
 puts "the test resulted in a false-value"
 
 puts "the test resulted in a false-value"
 
 
end
 
end
 
+
</syntaxhighlight>
 
وستكون النتيجة طباعة: 
 
وستكون النتيجة طباعة: 
 
+
<syntaxhighlight lang="text">
 +
“the test resulted in a false-value”
 +
</syntaxhighlight>
 
كما يمكنك أن تضيف أيّ عدد من الاختبارات الإضافيّة لبنية if باستخدام elsif. وكلّ شرط في elsif ينفّذ طالما كانت جميع الاختبارات السابقة له مساويةً إلى false:
 
كما يمكنك أن تضيف أيّ عدد من الاختبارات الإضافيّة لبنية if باستخدام elsif. وكلّ شرط في elsif ينفّذ طالما كانت جميع الاختبارات السابقة له مساويةً إلى false:
 
+
<syntaxhighlight lang="ruby">
 
a = 1
 
a = 1
 
 
if a == 0
 
if a == 0
 
 
 puts "a is zero"
 
 puts "a is zero"
 
 
elsif a == 1
 
elsif a == 1
 
 
 puts "a is one"
 
 puts "a is one"
 
 
else
 
else
 
 
 puts "a is some other value"
 
 puts "a is some other value"
 
 
end
 
end
 
+
</syntaxhighlight>
 
وتكون النتيجة “a is one” وذلك لأنّ 1 لا يساوي 0، و else تنفّذ فقط عندما لا يوجد ايّ اختبار محقّق فوقها. 
 
وتكون النتيجة “a is one” وذلك لأنّ 1 لا يساوي 0، و else تنفّذ فقط عندما لا يوجد ايّ اختبار محقّق فوقها. 
 
 
بمجرّد أن يتحقّق أيّ اختبار سواء في if أو في elsif تعدّ بنية if قد اكتملت ولن تجرى أيّة اختبارات أخرى. وكما هو الحال بالنّسبة للبنية if، يمكن للبنية elsif أن تتبعها then. 
 
بمجرّد أن يتحقّق أيّ اختبار سواء في if أو في elsif تعدّ بنية if قد اكتملت ولن تجرى أيّة اختبارات أخرى. وكما هو الحال بالنّسبة للبنية if، يمكن للبنية elsif أن تتبعها then. 
 
 
في المثال التالي ستكون النتيجة طباعة "a is one" فقط:
 
في المثال التالي ستكون النتيجة طباعة "a is one" فقط:
 
+
<syntaxhighlight lang="ruby">
 
a = 1
 
a = 1
 
 
if a == 0
 
if a == 0
 
 
 puts "a is zero"
 
 puts "a is zero"
 
 
elsif a == 1
 
elsif a == 1
 
 
 puts "a is one"
 
 puts "a is one"
 
 
elsif a >= 1
 
elsif a >= 1
 
 
 puts "a is greater than or equal to one"
 
 puts "a is greater than or equal to one"
 
 
else
 
else
 
 
 puts "a is some other value"
 
 puts "a is some other value"
 
 
end
 
end
 
+
</syntaxhighlight>
 
الاختبارات الشرطيّة الخاصّة بالبنية if و elsif قد يكون لها تأثيرات جانبيّة، والحالة الأكثر شيوعًا هي الاحتفاظ بقيمة لمتغيّر محليّ:
 
الاختبارات الشرطيّة الخاصّة بالبنية 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>
 
القيمة النّاتجة لبنية if هي آخر قيمة تنفّذ في هذه البنية.
 
القيمة النّاتجة لبنية if هي آخر قيمة تنفّذ في هذه البنية.
 
 
== تعبير if الثلاثي ==
 
== تعبير if الثلاثي ==
 
يمكنك أيضًا كتابة بنية if-then-else باستخدام ? و : وهي ما تسمى بتعبير if الثلاثي:
 
يمكنك أيضًا كتابة بنية if-then-else باستخدام ? و : وهي ما تسمى بتعبير if الثلاثي:
 
 
input_type = gets =~ /hello/i ? "greeting" : "other"
 
input_type = gets =~ /hello/i ? "greeting" : "other"
 
 
وهي تكافئ هذه البنية:
 
وهي تكافئ هذه البنية:
 
+
<syntaxhighlight lang="ruby">
 
input_type =
 
input_type =
 
 
 if gets =~ /hello/i
 
 if gets =~ /hello/i
 
 
   "greeting"
 
   "greeting"
 
 
 else
 
 else
 
 
   "other"
 
   "other"
 
 
 end 
 
 end 
 
+
</syntaxhighlight>
 
رغم أنّ تعبير if الثلاثيّ مختصر أكثر من الشكل الاعتيادي للبنية إلا أنّه من المفضّل لسهولة القراءة ألا يستخدم إلا للاختبارات البسيطة. تجنب أيضًا أن تُدخل أكثر من ثلاثيّ شرطي في نفس البنية كي لا يصبح الأمر مربكًا.
 
رغم أنّ تعبير if الثلاثيّ مختصر أكثر من الشكل الاعتيادي للبنية إلا أنّه من المفضّل لسهولة القراءة ألا يستخدم إلا للاختبارات البسيطة. تجنب أيضًا أن تُدخل أكثر من ثلاثيّ شرطي في نفس البنية كي لا يصبح الأمر مربكًا.
 
 
== بنية unless ==
 
== بنية unless ==
 
بنية unless هي النقيض لبنية if إذ أنّ الكتلة البرمجيّة فيها تنفّذ عندما يحقّق الاختبار الشرطيّ قيمة false:
 
بنية 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>
 
ولا شيء يطبع هنا إذ أنّ true لا تساوي قيمة خطأ:
 
ولا شيء يطبع هنا إذ أنّ true لا تساوي قيمة خطأ:
 
 
يمكنك أيضًا الاستغناء عن then أو كتابتها كما هو الحال في if.
 
يمكنك أيضًا الاستغناء عن then أو كتابتها كما هو الحال في if.
 
 
لاحظ أنّ بنية unless الأخير تكافئ تمامًا:
 
لاحظ أنّ بنية 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>
 
كما بإمكانك استخدام else أيضًا مع unless:
 
كما بإمكانك استخدام else أيضًا مع unless:
 
+
<syntaxhighlight lang="ruby">
 
unless true
 
unless true
 
 
 puts "the value is false"
 
 puts "the value is false"
 
 
else
 
else
 
 
 puts "the value is true"
 
 puts "the value is true"
 
 
end
 
end
 
+
</syntaxhighlight>
 
وتكون النتيجة طباعة “the value is true” من else:
 
وتكون النتيجة طباعة “the value is true” من else:
 
 
ليس بإمكانك استخدام elsif مع بنية unless.
 
ليس بإمكانك استخدام elsif مع بنية unless.
 
 
القيمة الناتجة عن بنية unless هي آخر قيمة تم تنفيذها في هذه البنية.
 
القيمة الناتجة عن بنية unless هي آخر قيمة تم تنفيذها في هذه البنية.
 
 
If و unless المعدِّلتان 
 
If و unless المعدِّلتان 
 
 
يمكن استخدام if و unless أيضًا لتعديل تعبير برمجيّ، وحينها يصبح الجزء الأيسر هو الجزء التنفيذي then والجزء الأيمن هو الاختبار الشرطيّ:
 
يمكن استخدام if و unless أيضًا لتعديل تعبير برمجيّ، وحينها يصبح الجزء الأيسر هو الجزء التنفيذي then والجزء الأيمن هو الاختبار الشرطيّ:
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
a += 1 if a.zero?
 
a += 1 if a.zero?
 
 
p a
 
p a
 
+
</syntaxhighlight>
 
هذا يطبع 1.
 
هذا يطبع 1.
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
a += 1 unless a.zero?
 
a += 1 unless a.zero?
 
 
p a 
 
p a 
 
+
</syntaxhighlight>
 
هذا يطبع 0.
 
هذا يطبع 0.
 
 
صحيح أنّ if المعدِّلة والعاديّة لهما شرط اختباريّ وجزء تنفيذيّ، إلا أنّهما ليسا متطابقين على وجه الدّقة وذلك بسبب اختلاف ترتيب كلّ منهما في مفسّر اللغة. هذا المثال يوضّح الفرق:
 
صحيح أنّ if المعدِّلة والعاديّة لهما شرط اختباريّ وجزء تنفيذيّ، إلا أنّهما ليسا متطابقين على وجه الدّقة وذلك بسبب اختلاف ترتيب كلّ منهما في مفسّر اللغة. هذا المثال يوضّح الفرق:
 
+
<syntaxhighlight lang="ruby">
 
p a if a = 0.zero?
 
p a if a = 0.zero?
 
+
</syntaxhighlight>
 
هذا سيسبّب ظهور الخطأ: NameError “undefined local variable or method `a'” 
 
هذا سيسبّب ظهور الخطأ: NameError “undefined local variable or method `a'” 
 
 
عندما يحلّل مفسّر اللغة هذا التعبير فإنّه يصادف بداية a ويعدّه استدعاء لتابع ضمن كتلة then، ولاحقًا يرى الإسناد إلى a في الشرط الاختباريّ ويعدّها متغيّرًا محليًّا. 
 
عندما يحلّل مفسّر اللغة هذا التعبير فإنّه يصادف بداية a ويعدّه استدعاء لتابع ضمن كتلة then، ولاحقًا يرى الإسناد إلى a في الشرط الاختباريّ ويعدّها متغيّرًا محليًّا. 
 
 
يبدأ تنفيذ هذا السّطر بتنفيذ الشّرط الاختباريّ a=0.zero?، وبما أنّ الشّرط محقّق سينتقل التنفيذ إلى الكتلة then وفيها p a والتي يعدّها تابعًا ويجد أنّ هذا التّابع غير موجود. هذا ما يسبّب ظهور خطأ NameError.
 
يبدأ تنفيذ هذا السّطر بتنفيذ الشّرط الاختباريّ a=0.zero?، وبما أنّ الشّرط محقّق سينتقل التنفيذ إلى الكتلة then وفيها p a والتي يعدّها تابعًا ويجد أنّ هذا التّابع غير موجود. هذا ما يسبّب ظهور خطأ NameError.
 
 
ذات الحالة تنطبق على unless.
 
ذات الحالة تنطبق على unless.
 
 
== بنية case == 
 
== بنية case == 
 
 
يمكن استخدام بنية case بطريقتين.
 
يمكن استخدام بنية case بطريقتين.
 
 
الاستخدام الشائع لها أن تقارن كائنًا ما مقابل أنماط مختلفة، وتتمّ المطابقة مع هذه الأنماط باستخدام تابع +===+ والذي يقابله تابع +==+ من الصنف Object. أم الأصناف الأخرى فعليها أن تعيد تعريف التابع ليأخذ سلوكًا ذا معنى. انظر Module#===‎ و Regexp#===‎ للحصول على أمثلة عملية.
 
الاستخدام الشائع لها أن تقارن كائنًا ما مقابل أنماط مختلفة، وتتمّ المطابقة مع هذه الأنماط باستخدام تابع +===+ والذي يقابله تابع +==+ من الصنف Object. أم الأصناف الأخرى فعليها أن تعيد تعريف التابع ليأخذ سلوكًا ذا معنى. انظر Module#===‎ و Regexp#===‎ للحصول على أمثلة عملية.
 
 
هذا مثال عن استخدام case لمقارنة سلسلة محرفية (string) مع نمط:
 
هذا مثال عن استخدام case لمقارنة سلسلة محرفية (string) مع نمط:
 
+
<syntaxhighlight lang="ruby">
 
case "12345"
 
case "12345"
 
 
when /^1/
 
when /^1/
 
 
 puts "the string starts with one"
 
 puts "the string starts with one"
 
 
else
 
else
 
 
 puts "I don't know what the string starts with"
 
 puts "I don't know what the string starts with"
 
 
end
 
end
 
+
</syntaxhighlight>
 
هنا تُقارن السلسلة المحرفيّة "12345" مع النمط /^1/ وذلك باستدعاء ‎/^1/ === "12345"‎ والذي يعيد قيمة true. وكما هو الحال في بنية if، تنفّذ الكتلة البرمجيّة التابعة لأوّل اختبار شرطيّ يتحقّق، وكل الحالات الأخرى تُتجاهل. وفي حال عدم وجود أي نمط مطابق تُنفّذ كتلة else. 
 
هنا تُقارن السلسلة المحرفيّة "12345" مع النمط /^1/ وذلك باستدعاء ‎/^1/ === "12345"‎ والذي يعيد قيمة true. وكما هو الحال في بنية if، تنفّذ الكتلة البرمجيّة التابعة لأوّل اختبار شرطيّ يتحقّق، وكل الحالات الأخرى تُتجاهل. وفي حال عدم وجود أي نمط مطابق تُنفّذ كتلة else. 
 
 
كلّ من else و then اختياريّين، بنية case التالية تعطي نفس النتيجة للبنية السابقة:
 
كلّ من else و then اختياريّين، بنية case التالية تعطي نفس النتيجة للبنية السابقة:
 
+
<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>
 
كما بإمكانك إدراج أكثر من شرط اختباريّ معًا ضمن when:
 
كما بإمكانك إدراج أكثر من شرط اختباريّ معًا ضمن 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>
 
سيجرّب مفسّر اللغة كل شرط على حدة وفق الترتيب، بداية يختبر ‎/^1/ === "2"‎ والذي يُرجع false، ثمّ يختبر "2" === "2" والذي يعيد true، فيطبع في النّهاية: “the string starts with one or is '2'” 
 
سيجرّب مفسّر اللغة كل شرط على حدة وفق الترتيب، بداية يختبر ‎/^1/ === "2"‎ والذي يُرجع false، ثمّ يختبر "2" === "2" والذي يعيد true، فيطبع في النّهاية: “the string starts with one or is '2'” 
 
 
بإمكانك كتابة then على نفس السطر بعد شرط when مباشرة، عادة ما يُستخدم هذا الأسلوب لكتابة كتلة then على نفس السّطر مع الشرط الخاصّ بها:
 
بإمكانك كتابة then على نفس السطر بعد شرط when مباشرة، عادة ما يُستخدم هذا الأسلوب لكتابة كتلة then على نفس السّطر مع الشرط الخاصّ بها:
 
+
<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
 
 
when 3    then puts "a is three"
 
when 3    then puts "a is three"
 
 
else           puts "I don't know what a is"
 
else           puts "I don't know what a is"
 
 
end
 
end
 
+
</syntaxhighlight>
 
الطريقة الثانية لكتابة بنية case تشابه بنية if-elsif:
 
الطريقة الثانية لكتابة بنية case تشابه بنية if-elsif:
 
+
<syntaxhighlight lang="ruby">
 
a = 2
 
a = 2
 
 
case
 
case
 
 
when a == 1, a == 2
 
when a == 1, a == 2
 
 
 puts "a is one or two"
 
 puts "a is one or two"
 
 
when a == 3
 
when a == 3
 
 
 puts "a is three"
 
 puts "a is three"
 
 
else
 
else
 
 
 puts "I don't know what a is"
 
 puts "I don't know what a is"
 
 
end
 
end
 
+
</syntaxhighlight>
 
وبالمثل، كل من then و else اختياريّتين.
 
وبالمثل، كل من then و else اختياريّتين.
 
 
القيمة الناتجة عن بنية case هي آخر قيمة تُنفّذ في البنية.
 
القيمة الناتجة عن بنية case هي آخر قيمة تُنفّذ في البنية.
 
 
== حلقة while التكراريّة ==
 
== حلقة while التكراريّة ==
 
تُنفّذ حلقة while التكراريّة طالما أنّ شرطها محقّق:
 
تُنفّذ حلقة while التكراريّة طالما أنّ شرطها محقّق:
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
while a < 10 do
 
while a < 10 do
 
 
 p a
 
 p a
 
 
 a += 1
 
 a += 1
 
 
end
 
end
 
 
p a
 
p a
 
+
</syntaxhighlight>
 
هذا يطبع الأرقام من 0 إلى 10، فالشرط a<10 يُختبَر قبل دخول كل حلقة ومن ثمّ ينفّذ ما بداخلها، ومن ثمّ يختبر الشرط مجدّدًا. وعندما تكون نتيجة الاختبار false يتوقف تنفيذ الحلقة التّكرارية.
 
هذا يطبع الأرقام من 0 إلى 10، فالشرط a<10 يُختبَر قبل دخول كل حلقة ومن ثمّ ينفّذ ما بداخلها، ومن ثمّ يختبر الشرط مجدّدًا. وعندما تكون نتيجة الاختبار false يتوقف تنفيذ الحلقة التّكرارية.
 
 
الكلمة المحجوزة do اختياريّة، فالحلقة التالية مكافئة للحلقة السابقة:
 
الكلمة المحجوزة do اختياريّة، فالحلقة التالية مكافئة للحلقة السابقة:
 
+
<syntaxhighlight lang="ruby">
 
while a < 10
 
while a < 10
 
 
 p a
 
 p a
 
 
 a += 1
 
 a += 1
 
 
end
 
end
 
+
</syntaxhighlight>
 
نتيجة حلقة while التكرارية تساوي nil إلا إذا استٌخدمت break لتزوّدها بقيمة.
 
نتيجة حلقة while التكرارية تساوي nil إلا إذا استٌخدمت break لتزوّدها بقيمة.
 
 
== حلقة until التكرارية ==
 
== حلقة until التكرارية ==
 
تنفّذ هذه الحلقة طالما أنّ شرطها غير محقّق:
 
تنفّذ هذه الحلقة طالما أنّ شرطها غير محقّق:
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
until a > 10 do
 
until a > 10 do
 
 
 p a
 
 p a
 
 
 a += 1
 
 a += 1
 
 
end
 
end
 
 
p a
 
p a
 
+
</syntaxhighlight>
 
هذا يطبع الأرقام من 0 إلى 11. وكما هو الحال في while فالشرط a>10 يُختبر في كلّ مرة قبل دخول الحلقة، ومن ثمّ يٌنفّذ محتواها، إذا كان الشّرط غير محقق فستستمرّ الحلقة بالتكرار.
 
هذا يطبع الأرقام من 0 إلى 11. وكما هو الحال في while فالشرط a>10 يُختبر في كلّ مرة قبل دخول الحلقة، ومن ثمّ يٌنفّذ محتواها، إذا كان الشّرط غير محقق فستستمرّ الحلقة بالتكرار.
 
 
وكما هو الحال في while فإنّ كلمة do اختياريّة. وكذلك القيمة الناتجة من الحلقة تبقى nil إلا إذا استخدمت break.
 
وكما هو الحال في while فإنّ كلمة do اختياريّة. وكذلك القيمة الناتجة من الحلقة تبقى nil إلا إذا استخدمت break.
 
 
== حلقة for التكرارية ==
 
== حلقة for التكرارية ==
 
حلقة for التكرارية تتكون من for متبوعة بمتغيّرسيحتوي معامل التّكرار (iteration argument) ومن ثمّ كلمة in ثم القيم التي ستكرّر الحلقة وفقها. أمّا do فهي اختياريّة:
 
حلقة for التكرارية تتكون من for متبوعة بمتغيّرسيحتوي معامل التّكرار (iteration argument) ومن ثمّ كلمة in ثم القيم التي ستكرّر الحلقة وفقها. أمّا do فهي اختياريّة:
 
+
<syntaxhighlight lang="ruby">
 
for value in [1, 2, 3] do
 
for value in [1, 2, 3] do
 
 
 puts value
 
 puts value
 
 
end
 
end
 
+
</syntaxhighlight>
 
يطبع 1 ثمّ 2 ثمّ 3 
 
يطبع 1 ثمّ 2 ثمّ 3 
 
 
إن استخدام for مشابه لاستخدام each إلّا أنّ الأولى لا تٌنشئ نطاقًا جديدًا للمتغيّرات.
 
إن استخدام for مشابه لاستخدام each إلّا أنّ الأولى لا تٌنشئ نطاقًا جديدًا للمتغيّرات.
 
 
نتيجة حلقة for التكراريّة هي آخر قيمة تصل إليها في التّكرار، إلا إذا استُخدمت break.
 
نتيجة حلقة for التكراريّة هي آخر قيمة تصل إليها في التّكرار، إلا إذا استُخدمت break.
 
 
نادرًا ما تُستخدم حلقة for في البرامج الحديثة المكتوبة بلغة روبي.
 
نادرًا ما تُستخدم حلقة for في البرامج الحديثة المكتوبة بلغة روبي.
 
 
== المعدِّلتان while و until ==
 
== المعدِّلتان while و until ==
 
كما هو الحال في if و unless، يمكن لحلقة while و until أن تكونا معدِّلتين:
 
كما هو الحال في if و unless، يمكن لحلقة while و until أن تكونا معدِّلتين:
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
a += 1 while a < 10
 
a += 1 while a < 10
 
 
p a # تطبع 10
 
p a # تطبع 10
 
 
استخدام until كمعدّلة:
 
استخدام until كمعدّلة:
 
 
a = 0
 
a = 0
 
 
a += 1 until a > 10
 
a += 1 until a > 10
 
 
p a # تطبع 11 
 
p a # تطبع 11 
 
+
</syntaxhighlight>
 
يمكنك استخدام begin و end مع حلقة while لتنفّذ محتوى الحلقة مرة واحدة قبل اختبار الشرط.
 
يمكنك استخدام begin و end مع حلقة while لتنفّذ محتوى الحلقة مرة واحدة قبل اختبار الشرط.
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
begin
 
begin
 
 
 a += 1
 
 a += 1
 
 
end while a < 10
 
end while a < 10
 
 
p a # تطبع 10
 
p a # تطبع 10
 
+
</syntaxhighlight>
 
إذا لم تستخدم أيًا من rescue أو ensure فستقوم لغة روبي بتحسين أيّ شيفرة تعامل مع الاستثناءات تمرّ عليها.
 
إذا لم تستخدم أيًا من rescue أو ensure فستقوم لغة روبي بتحسين أيّ شيفرة تعامل مع الاستثناءات تمرّ عليها.
 
 
== عبارة break ==
 
== عبارة break ==
 
استخدم break لمغادرة كتلة برمجيّة في وقت مبكر. في هذا المثال يتوقّف التكّرار على بقيّة العناصر في values إذا كان أحدها زوجيّ:
 
استخدم break لمغادرة كتلة برمجيّة في وقت مبكر. في هذا المثال يتوقّف التكّرار على بقيّة العناصر في values إذا كان أحدها زوجيّ:
 
+
<syntaxhighlight lang="ruby">
 
values.each do |value|
 
values.each do |value|
 
 
 break if value.even?
 
 break if value.even?
 
 
 # ...
 
 # ...
 
 
end
 
end
 
+
</syntaxhighlight>
 
يمكنك أيضًا أن توقف تنفيذ حلقة while باستخدام break:
 
يمكنك أيضًا أن توقف تنفيذ حلقة while باستخدام break:
 
+
<syntaxhighlight lang="ruby">
 
a = 0
 
a = 0
 
 
while true do
 
while true do
 
 
 p a
 
 p a
 
 
 a += 1
 
 a += 1
 
 
 break if a < 10
 
 break if a < 10
 
 
end
 
end
 
 
p a
 
p a
 
+
</syntaxhighlight>
 
هذا يطبع الرقمين 0 و 1 فقط.
 
هذا يطبع الرقمين 0 و 1 فقط.
 
 
تقبل break أن تمرّر لها قيمة تعيدها كنتيجة للبنية التي تقوم بإيقافها:
 
تقبل break أن تمرّر لها قيمة تعيدها كنتيجة للبنية التي تقوم بإيقافها:
 
+
<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?
 
 
end
 
end
 
 
p result # تطبع 4
 
p result # تطبع 4
 
+
</syntaxhighlight>
 
== عبارة next ==
 
== عبارة next ==
 
استخدم next لتتخطى ما تبقّى من الجولة الحاليّة في التكرار:
 
استخدم next لتتخطى ما تبقّى من الجولة الحاليّة في التكرار:
 
+
<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?
 
 
 value * 2
 
 value * 2
 
 
end
 
end
 
 
p result # تطبع [2, nil, 6]
 
p result # تطبع [2, nil, 6]
 
+
</syntaxhighlight>
 
تقبل next أن تمرّر لها معاملًا تُرجعه كنتيجة للجولة الحاليّة من الحلقة التّكرارية:
 
تقبل 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?
 
 
 value * 2
 
 value * 2
 
 
end
 
end
 
 
p result # نطبع [2, 2, 6]
 
p result # نطبع [2, 2, 6]
 
+
</syntaxhighlight>
 
== عبارة redo == 
 
== عبارة redo == 
 
 
استخدم عبارة redo لإعادة تنفيذ الجولة الحاليّة:
 
استخدم عبارة redo لإعادة تنفيذ الجولة الحاليّة:
 
+
<syntaxhighlight lang="ruby">
 
result = []
 
result = []
 
 
while result.length < 10 do
 
while result.length < 10 do
 
 
 result << result.length
 
 result << result.length
 
 
 redo if result.last.even?
 
 redo if result.last.even?
 
 
 result << result.length + 1
 
 result << result.length + 1
 
 
end
 
end
 
 
p result
 
p result
 
+
</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 من لغة روبي كان بإمكانك أن تستخدم retry في نفس الأماكن التي تستخدم فيها redo. لم يعد هذا متاحًا الآن، فاستخدام retry خارج كتلة rescue سيعطيك خطأ صيغة (SyntaxError). انظر الصفحة الخاصة بالاستثناءات لتعرف أكثر عن الاستخدام الصحيح لـ retry.
 
في الإصدار 1.8 من لغة روبي كان بإمكانك أن تستخدم retry في نفس الأماكن التي تستخدم فيها redo. لم يعد هذا متاحًا الآن، فاستخدام retry خارج كتلة rescue سيعطيك خطأ صيغة (SyntaxError). انظر الصفحة الخاصة بالاستثناءات لتعرف أكثر عن الاستخدام الصحيح لـ retry.
 
 
== القلاب (Flip-Flop) == 
 
== القلاب (Flip-Flop) == 
 
 
القلّاب هو بنية تحكّم نادرًا ما نراها، استخدامها الأساسي يكمن في معالجة النّصوص في برامج روبي ذات السّطر الواحد والمستخدمة بواسطة ruby -n أو ruby -p. 
 
القلّاب هو بنية تحكّم نادرًا ما نراها، استخدامها الأساسي يكمن في معالجة النّصوص في برامج روبي ذات السّطر الواحد والمستخدمة بواسطة ruby -n أو ruby -p. 
 
 
صيغة القلّاب هي كالتالي، بداية الشّرط الذي يعبّر عن دخول القلاب حالة التفعيل (on) ومن ثمّ نقطتين متتاليتين (..) أو ثلاثة نقاط (...)، ومن ثمّ الشرط الذي يعبّر عن انتقال القلّاب إلى حالة عدم التفعيل (off). وطالما أنّ القلّاب في حالة تفعيل فسيستمرّ بإعطاء نتيجة true، وإذا كان غير مفعلّ يعطي false. 
 
صيغة القلّاب هي كالتالي، بداية الشّرط الذي يعبّر عن دخول القلاب حالة التفعيل (on) ومن ثمّ نقطتين متتاليتين (..) أو ثلاثة نقاط (...)، ومن ثمّ الشرط الذي يعبّر عن انتقال القلّاب إلى حالة عدم التفعيل (off). وطالما أنّ القلّاب في حالة تفعيل فسيستمرّ بإعطاء نتيجة true، وإذا كان غير مفعلّ يعطي false. 
 
 
إليك مثالًا:
 
إليك مثالًا:
 
+
<syntaxhighlight lang="ruby">
 
selected = []
 
selected = []
 
 
0.upto 10 do |value|
 
0.upto 10 do |value|
 
 
 selected << value if value==2..value==8
 
 selected << value if value==2..value==8
 
 
end
 
end
 
 
p selected # يطبع [2, 3, 4, 5, 6, 7, 8]
 
p selected # يطبع [2, 3, 4, 5, 6, 7, 8]
 
+
</syntaxhighlight>
 
في المثال السابق نجد أنّ شرط التفعيل هو value==2. فالقلاب يكون ابتداءً في حالة عدم تفعيل لكل من القيمتين 0 و 1، لكنه يصبح مفعلًا عند 2 ويبقى كذلك حتى نصل إلى 8 وعندها "يقلب" حالته إلى off ويستمر كذلك لكل من 9 و 10. 
 
في المثال السابق نجد أنّ شرط التفعيل هو value==2. فالقلاب يكون ابتداءً في حالة عدم تفعيل لكل من القيمتين 0 و 1، لكنه يصبح مفعلًا عند 2 ويبقى كذلك حتى نصل إلى 8 وعندها "يقلب" حالته إلى off ويستمر كذلك لكل من 9 و 10. 
 
 
يجب أن يُستخدم القلاب في بنية شرطيّة مثل if أو while أو unless أو until أو غيرها، بما في ذلك أنواعها المعدِّلة.
 
يجب أن يُستخدم القلاب في بنية شرطيّة مثل if أو while أو unless أو until أو غيرها، بما في ذلك أنواعها المعدِّلة.
 
 
عندما تستخدم مجالًا متضمّنًا (..)، فإنّ شرط إلغاء التفعيل يقيّم عندما يتغيّر شرط التفعيل:
 
عندما تستخدم مجالًا متضمّنًا (..)، فإنّ شرط إلغاء التفعيل يقيّم عندما يتغيّر شرط التفعيل:
 
+
<syntaxhighlight lang="ruby">
 
selected = []
 
selected = []
 
 
0.upto 5 do |value|
 
0.upto 5 do |value|
 
 
 selected << value if value==2..value==2
 
 selected << value if value==2..value==2
 
 
end
 
end
 
 
p selected # يطبع [2]
 
p selected # يطبع [2]
 
+
</syntaxhighlight>
 
هنا كلا جانبي القلاب يقيّمان بحيث يقلب إلى on و off فقط عندما تكون القيمة مساوية للقيمة 2. وطالما أنّ القلاب أصبح مفعلًا في هذه الجولة فسيرجع قيمة true.
 
هنا كلا جانبي القلاب يقيّمان بحيث يقلب إلى on و off فقط عندما تكون القيمة مساوية للقيمة 2. وطالما أنّ القلاب أصبح مفعلًا في هذه الجولة فسيرجع قيمة true.
 
 
أمّا عندما تستخدم مجالاً مستبعِدًا (...) فإن شرط إلغاء التفعيل يقيّم في الجولة التالية: 
 
أمّا عندما تستخدم مجالاً مستبعِدًا (...) فإن شرط إلغاء التفعيل يقيّم في الجولة التالية: 
 
+
<syntaxhighlight lang="ruby">
 
selected = []
 
selected = []
 
 
0.upto 5 do |value|
 
0.upto 5 do |value|
 
 
 selected << value if value==2...value==2
 
 selected << value if value==2...value==2
 
 
end
 
end
 
 
p selected # يطبع [2, 3, 4, 5]
 
p selected # يطبع [2, 3, 4, 5]
 
+
</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 في توثيق روبي الرسمي]

مراجعة 22:34، 15 نوفمبر 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 لا تساوي قيمة خطأ: يمكنك أيضًا الاستغناء عن 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 والتي يعدّها تابعًا ويجد أنّ هذا التّابع غير موجود. هذا ما يسبّب ظهور خطأ 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 بالفعل، ولن تعود إليها مرّة أخرى.

المصادر