معالجة الاستثناءات في روبي

من موسوعة حسوب
مراجعة 08:45، 19 نوفمبر 2018 بواسطة جميل-بيلوني (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

يتمّ التعامل مع الاستثناءات بعد الكلمة rescue في الكتلة begin/end:

begin
 # الشيفرة التي قد تسبب ظهور استثناء برمجي
rescue
 # معالجة الاستثناء
end 

إذا كنت ضمن تابع، فلست بحاجة لاستخدام begin و end إلا إذا كنت ترغب بحدّ النّطاق الخاص بالاستثناء الذي ترغب بمعالجته:

def my_method
 # ...
rescue
 # ...
end

نفس الأمر يطبّق في الأصناف (classes) والوحدات (modules).

يمكنك إسناد استثناء إلى متغيّر محليّ باستخدام الرمز ‎=>‎ متبوعًا باسم المتغيّر، وذلك في نهاية السطر الخاص بالكلمة rescue:

begin
 # ...
rescue => exception
 warn exception.message
 raise # كرر ظهور الاستثناء
end

في الوضع الافتراضيّ، فإنّ الاستثناءات من النوع StandardError والأصناف المتفرعّة عنها يتم التعامل معها باستخدام rescue؛ لكنّك إن رغبت بحصر استثناءات معيّنة (والأصناف  الفرعية التابعة لها) لتعالجها على وجه التحديد، فيمكنك ذكرها ضمن قائمة بعد كلمة rescue:

begin
 # ...
rescue ArgumentError, NameError
 # NameError أو ArgumentError التعامل مع الاستثناءات من النوع
end

كما يمكنك التعامل مع الاستثناءات المختلفة بأساليب مختلفة:

begin
 # ...
rescue ArgumentError
 # ArgumentError التعامل مع الاستثناء من نوع 
rescue NameError
 # NameError التعامل مع الاستثناء من نوع
rescue
 # StandardError التعامل مع أي استثناء آخر يندرج تحت 
end

تتم مطابقة الاستثناءات في قسم rescue ابتداءً من الأعلى، وتطابق استثناءً واحدًا فقط. فإذا ظهر استثناء ArgumentError في الجزء begin، فلن يتمّ التعامل معه في الجزء StandardError.

يمكنك إعادة تنفيذ الجزء الذي ظهر فيه الاستثناء باستخدام retry:

begin
 # ...
rescue
 # begin افعل شيئًا يمكنه تغيير نتيجة الجزء الخاص بـ 
 retry
end

وعندها سيستمرّ التنفيذ من بداية كتلة begin، لذلك احذر من أن تكوّن حلقات تكرار لا نهائيّة.

كتلة rescue هي المكان الوحيد الصّحيح لإجراء إعادة المحاولة باستخدام retry ، وأيّ مكان آخر تستخدمها فيه سيسبب ظهور SyntaxError. لكنّك إن أردت إعادة تنفيذ كتلة معيّنة فعليك استخدام redo. انظر القسم الخاص ببنى التحكم لمزيد من التفاصيل.

إذا أردت أن تتأكد من تنفيذ جزء من الشيفرة سواءً تسبب بحدوث استثناء أو لا، فعليك عندئذٍ أن تستخدم ensure:

begin
 # ...
rescue
 # ...
ensure
 # هذا سينفذ دومًا
end

وقد ترغب أحيانًا بتنفيذ أوامر معيّنة فقط في حال لم يظهر أي استثناء:

begin
 # ...
rescue
 # ...
else
 # هذا ينفذ فقط في حالة عدم ظهور أيّ استثناء
ensure
 # ...
end

المصادر