ใช่ensure
รับรองว่าจะมีการประเมินรหัสอยู่เสมอ ensure
นั่นเป็นเหตุผลที่มันเรียกว่า ดังนั้นจึงจะเทียบเท่ากับ C # ของ Java และ finally
's
โฟลว์ทั่วไปของbegin
/ rescue
/ else
/ ensure
/ end
มีลักษณะดังนี้:
begin
# something which might raise an exception
rescue SomeExceptionClass => some_variable
# code that deals with some exception
rescue SomeOtherException => some_other_variable
# code that deals with some other exception
else
# code that runs only if *no* exception was raised
ensure
# ensure that this code always runs, no matter what
# does not change the final value of the block
end
คุณสามารถปล่อยออกrescue
, หรือensure
else
คุณยังสามารถละทิ้งตัวแปรซึ่งในกรณีนี้คุณจะไม่สามารถตรวจสอบข้อยกเว้นในโค้ดการจัดการข้อยกเว้นของคุณ (ดีคุณสามารถใช้ตัวแปรยกเว้นทั่วโลกในการเข้าถึงข้อยกเว้นสุดท้ายที่ถูกยกขึ้น แต่ที่ hacky นิด ๆ หน่อย ๆ .) และคุณสามารถออกจากชั้นยกเว้นในกรณีที่มีข้อยกเว้นทุกสิ่งที่สืบทอดจากStandardError
จะถูกจับ (โปรดทราบว่านี้ไม่ได้หมายความว่าทุกข้อยกเว้นจะถูกจับเพราะมีข้อยกเว้นซึ่งเป็นกรณีของException
แต่ไม่StandardError
. ยกเว้นส่วนใหญ่ที่รุนแรงมากว่าการประนีประนอมความสมบูรณ์ของโปรแกรมเช่นSystemStackError
, NoMemoryError
, SecurityError
, NotImplementedError
, LoadError
, SyntaxError
, ScriptError
, Interrupt
,SignalException
หรือSystemExit
.)
บล็อกบางรูปแบบบล็อกข้อยกเว้นโดยนัย ตัวอย่างเช่นคำจำกัดความของวิธีการนั้นยังมีข้อยกเว้นบล็อกโดยปริยายดังนั้นแทนที่จะเขียน
def foo
begin
# ...
rescue
# ...
end
end
คุณเขียนแค่
def foo
# ...
rescue
# ...
end
หรือ
def foo
# ...
ensure
# ...
end
เช่นเดียวกับclass
คำจำกัดความและmodule
คำจำกัดความ
อย่างไรก็ตามในกรณีเฉพาะที่คุณถามเกี่ยวกับว่ามีสำนวนที่ดีกว่ามาก โดยทั่วไปเมื่อคุณทำงานกับทรัพยากรบางอย่างที่คุณจำเป็นต้องล้างข้อมูลในตอนท้ายคุณทำได้โดยการส่งบล็อกไปยังวิธีการที่ทำการล้างข้อมูลทั้งหมดให้คุณ มันคล้ายกับusing
บล็อกใน C # ยกเว้นว่า Ruby มีประสิทธิภาพเพียงพอที่คุณไม่ต้องรอให้มหาปุโรหิตของ Microsoft ลงมาจากภูเขาและเปลี่ยนคอมไพเลอร์ให้คุณ ใน Ruby คุณสามารถสร้างมันเองได้:
# This is what you want to do:
File.open('myFile.txt', 'w') do |file|
file.puts content
end
# And this is how you might implement it:
def File.open(filename, mode='r', perm=nil, opt=nil)
yield filehandle = new(filename, mode, perm, opt)
ensure
filehandle&.close
end
และสิ่งที่คุณรู้: นี้มีอยู่ในห้องสมุดแกนเป็นFile.open
แล้ว แต่มันเป็นรูปแบบทั่วไปที่คุณสามารถใช้ในรหัสของคุณเองเช่นกันสำหรับการใช้งานการล้างทรัพยากร (เช่น la using
C #) หรือธุรกรรมหรือสิ่งอื่นใดที่คุณอาจนึกถึง
เฉพาะกรณีที่ไม่สามารถใช้งานได้หากการรับและการปล่อยทรัพยากรถูกกระจายไปทั่วส่วนต่าง ๆ ของโปรแกรม แต่ถ้าเป็นภาษาท้องถิ่นในตัวอย่างของคุณคุณสามารถใช้บล็อคทรัพยากรเหล่านี้ได้อย่างง่ายดาย
BTW: ในปัจจุบัน C # using
เป็นจริงที่ไม่จำเป็นเพราะคุณสามารถใช้บล็อกทรัพยากรสไตล์ทับทิมเอง:
class File
{
static T open<T>(string filename, string mode, Func<File, T> block)
{
var handle = new File(filename, mode);
try
{
return block(handle);
}
finally
{
handle.Dispose();
}
}
}
// Usage:
File.open("myFile.txt", "w", (file) =>
{
file.WriteLine(contents);
});
begin
บล็อก