سؤال

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

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

باستخدام ضمان يعمل:

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

ولكن المستخدمين من فئة يجب أن نتذكر أن تفعل كل begin-الإنقاذ-ضمان chacha في كل مرة تفتح الأسلوب يجب أن يكون.

هكذا على سبيل المثال, سوف يكون فئة التالية:

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

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

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

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

المحلول

بحيث يمكن للمستخدمين لا "يجب أن نتذكر أن تفعل كل begin-الإنقاذ-ضمان chacha"الجمع بين rescue/ensure مع yield.

class SomeResource
  ...
  def SomeResource.use(*resource_args)
    # create resource
    resource = SomeResource.new(*resource_args) # pass args direct to constructor
    # export it
    yield resource
  rescue
    # known error processing
    ...
  ensure
    # close up when done even if unhandled exception thrown from block
    resource.close
  end
  ...
end

رمز العميل يمكن استخدامه على النحو التالي:

SomeResource.use(connection_string) do | resource |
  resource.do_something
  ... # whatever else
end
# after this point resource has been .close()d

في الواقع هذه هي الطريقة File.open تعمل صنع أول الجواب مربكا في أفضل (حسنا كان بلدي زملاء العمل).

File.open("testfile") do |f|
  # .. process - may include throwing exceptions
end
# f is guaranteed closed after this point even if exceptions are 
# thrown during processing

نصائح أخرى

ماذا عن yieldجي الموارد كتلة ؟ على سبيل المثال:

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

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

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

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

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

انظر 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

هذا سوف تكون مألوفة لمستخدمي Python, Java أو C# في أنه يعمل مثل try / catch / أخيرا.

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