ruby - راي في روبي(أو، كيفية إدارة الموارد في روبي)




resources destructor (3)

وأنا أعلم أنه من خلال التصميم الذي لا يمكنك السيطرة على ما يحدث عندما يتم تدمير كائن. وأنا أيضا على بينة من تحديد بعض طريقة الطبقة كمنهي.

ومع ذلك هو لغة روبي ل راي C ++ (يتم تهيئة الموارد في منشئ، مغلقة في ديستروكتور)؟ كيف يدير الأشخاص الموارد المستخدمة داخل الكائنات حتى عند حدوث أخطاء أو استثناءات؟

استخدام أعمال الضمان:

f = File.open("testfile")
begin
  # .. process
rescue
  # .. handle error
ensure
  f.close unless f.nil?
end

ولكن مستخدمي الطبقة يجب أن نتذكر أن تفعل كله تبدأ الإنقاذ - ضمان تشاتشا في كل مرة تحتاج طريقة مفتوحة ليتم استدعاؤها.

على سبيل المثال، سأحصل على الدرجة التالية:

class SomeResource
 def initialize(connection_string)
   @resource_handle = ...some mojo here...
 end

 def do_something()
   begin
    @resource_handle.do_that()
    ...
   rescue
    ...
   ensure
 end

 def close
  @resource_handle.close
 end

end

لن يتم إغلاق المورد إذا كان الاستثناء سبب من قبل فئة أخرى ومخارج البرنامج النصي.

أو هي المشكلة أكثر من أنا ما زلت تفعل هذا أيضا C ++ - مثل؟


انظر http://www.rubycentral.com/pickaxe/tut_exceptions.html

في روبي، يمكنك استخدام بيان ensure :

f = File.open("testfile")
begin
  # .. process
rescue
  # .. handle error
ensure
  f.close unless f.nil?
end

وسيكون هذا مألوفا لمستخدمي بايثون، جافا، أو C # في أنه يعمل مثل محاولة / الصيد / أخيرا.


ماذا عن yield على الموارد إلى كتلة؟ مثال:

File.open("testfile") do |f|
  begin
    # .. process
  rescue
    # .. handle error
  end
end

أو هي المشكلة أكثر من أنا ما زلت تفعل هذا أيضا C ++ - مثل؟

نعم فمن منذ في C ++ ديالوكاتيون الموارد يحدث ضمنا لكل شيء على المكدس. كومة أونوند = الموارد دمرت = ديستروكتورس ودعا ومن هناك يمكن الإفراج عن الأشياء. منذ روبي لا يوجد لديه المدمرات لا يوجد "القيام بذلك عندما يتم كل شيء آخر مع" مكان منذ جمع الاستيلاء يمكن أن يتأخر عدة دورات من أين أنت. لديك اللمسات الأخيرة ولكن يطلق عليهم "في طي النسيان" (ليس كل شيء متاح لهم) وأنها تحصل على دعا على غ.

لذلك إذا كنت عقد مقبض لبعض الموارد التي يتم الافراج بشكل أفضل تحتاج إلى الإفراج عنه بشكل صريح. والواقع أن المصطلح الصحيح للتعامل مع هذا النوع من الوضع هو

def with_shmoo
  handle = allocate_shmoo
  yield(handle)
ensure
  handle.close
end




finalizer