معالجة الاستثناءات في روبي
يتمّ التعامل مع الاستثناءات بعد الكلمة 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