ما الفرق بين رفع الاستثناءات ورمي الاستثناءات في روبي؟

StackOverflow https://stackoverflow.com/questions/51021

  •  09-06-2019
  •  | 
  •  

سؤال

لدى روبي آليتان مختلفتان للاستثناءات:رمي/قبض ورفع/إنقاذ.

لماذا لدينا اثنان؟

متى يجب عليك استخدام واحد وليس الآخر؟

هل كانت مفيدة؟

المحلول

أظن http://hasno.info/Ruby-gotchas-and-caveats لديه تفسير لائق للفرق:

الالتقاط/الرمي ليس مثل الرفع/الإنقاذ.يسمح لك الالتقاط/الرمي بالخروج بسرعة من الكتل مرة أخرى إلى النقطة التي يتم فيها تعريف الالتقاط لرمز معين، ويعتبر رفع الإنقاذ هو الاستثناء الحقيقي للتعامل مع الأشياء التي تتضمن كائن الاستثناء.

نصائح أخرى

  • raise, fail, rescue, ، و ensure مقبض أخطاء, ، المعروف أيضًا باسم استثناءات
  • throw و catch نكون تدفق التحكم

على عكس اللغات الأخرى ، لا يتم استخدام رمية Ruby و Catch للاستثناءات.بدلاً من ذلك ، فإنها توفر وسيلة لإنهاء التنفيذ مبكرًا عند عدم الحاجة إلى مزيد من العمل.(جريم، 2011)

إنهاء مستوى واحد من تدفق التحكم، مثل while حلقة، يمكن القيام بها بطريقة بسيطة return.يمكن إنهاء العديد من مستويات تدفق التحكم، مثل الحلقة المتداخلة throw.

على الرغم من أن آلية الاستثناء الخاصة بالرفع والإنقاذ تعتبر رائعة للتخلي عن التنفيذ عندما تسوء الأمور، إلا أنه من الجيد أحيانًا أن تكون قادرًا على القفز من بعض البنية المتداخلة أثناء المعالجة العادية.هذا هو المكان الذي يكون فيه الإمساك والرمي مفيدًا.(توماس وهانت، 2001)

مراجع

  1. جريم، افيدي."رمي ، اصطياد ، ارفع ، إنقاذ ... أنا مرتبك للغاية!" مدونة Rubylearning.ن.ب، 11 يوليو 2011.ويب.1 يناير2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. توماس وديف وأندرو هانت."برمجة روبي." :دليل المبرمج العملي.ن.ب، 2001.ويب.29 سبتمبر2015. http://Ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html.

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise يقدم شرحًا ممتازًا وأشك في أنني أستطيع تحسينه.لتلخيص ذلك، أخذ بعض نماذج التعليمات البرمجية من منشور المدونة بينما أذهب:

  1. raise/rescue هي أقرب نظائرها إلى throw/catch البناء الذي تعرفه من اللغات الأخرى (أو من لغة Python raise/except).إذا واجهت حالة خطأ وسوف تفعل ذلك throw أكثر من ذلك بلغة أخرى، يجب عليك raise في روبي.

  2. روبي throw/catch يتيح لك كسر التنفيذ وتسلق المكدس بحثًا عن ملف catch (يحب raise/rescue يفعل)، ولكن ليس المقصود حقًا حالات الخطأ.يجب استخدامه نادرًا، وهو موجود فقط عند "السير في المكدس حتى تجد ملفًا مطابقًا catch"السلوك منطقي بالنسبة للخوارزمية التي تكتبها ولكن لن يكون من المنطقي التفكير في throw بما يتوافق مع حالة الخطأ.

    ما هو الصيد والرمي المستخدم في روبي؟ يقدم بعض الاقتراحات حول الاستخدامات الجيدة لـ throw/catch بناء.

تشمل الاختلافات السلوكية الملموسة بينهما ما يلي:

  • rescue Foo سوف ينقذ حالات Foo بما في ذلك الفئات الفرعية من Foo. catch(foo) سوف يمسك فقط نفس الكائن، Foo.ليس فقط لا يمكنك المرور catch اسم فئة لالتقاط مثيلات منه، لكنه لن يقوم حتى بإجراء مقارنات المساواة.على سبيل المثال

    catch("foo") do
      throw "foo"
    end
    

    سوف أعطيك UncaughtThrowError: uncaught throw "foo" (أو ArgumentError في إصدارات روبي قبل 2.2)

  • يمكن إدراج شروط الإنقاذ المتعددة...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end
    

    بينما متعددة catchيجب أن تكون متداخلة ...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • عارية rescue يعادل rescue StandardError وهو بناء اصطلاحي.عارية catch"، يحب catch() {throw :foo}, ، لن يمسك أي شيء أبدًا ولا ينبغي استخدامه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top