Evet, ensure
kodun her zaman değerlendirilmesini sağlar. Bu yüzden denir ensure
. Yani, Java ve C # 'lara eşdeğerdir finally
.
begin
/ rescue
/ else
/ ensure
/ Genel akışı end
şu şekildedir:
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
Dışarıda bırakabilirsin rescue
, ensure
ya else
. Değişkenleri de dışarıda bırakabilirsiniz, bu durumda istisna işleme kodunuzdaki istisnayı inceleyemezsiniz. (Eh, yükseltilen son istisnaya erişmek için her zaman küresel istisna değişkenini kullanabilirsiniz, ancak bu biraz çirkin.) Ve istisna sınıfını dışarıda bırakabilirsiniz, bu durumda devralınan tüm istisnalar StandardError
yakalanır. (Not bu anlamına gelmez Lütfen bu tüm orada örnekleri olan istisnalar, çünkü istisnalar yakalanırlar Exception
ama StandardError
. Çoğunlukla çok şiddetli istisnalar uzlaşmanın gibi programın bütünlüğü SystemStackError
, NoMemoryError
, SecurityError
, NotImplementedError
, LoadError
, SyntaxError
, ScriptError
, Interrupt
,SignalException
veya SystemExit
.)
Bazı bloklar örtük istisna blokları oluşturur. Örneğin, yöntem tanımları örtük olarak da istisna bloklarıdır, bu yüzden yazmak yerine
def foo
begin
# ...
rescue
# ...
end
end
sadece yaz
def foo
# ...
rescue
# ...
end
veya
def foo
# ...
ensure
# ...
end
Aynısı class
tanımlar ve module
tanımlar için de geçerlidir .
Ancak, sorduğunuz belirli bir durumda, aslında çok daha iyi bir deyim vardır. Genel olarak, sonunda temizlemeniz gereken bir kaynakla çalıştığınızda, bunu sizin için tüm temizliği yapan bir yönteme geçirerek yaparsınız. using
C # 'daki bir bloğa benzer , ancak Ruby aslında Microsoft'un yüksek rahiplerinin dağdan inmesini ve derleyicisini sizin için nezaketle değiştirmesini beklemek zorunda kalmayacak kadar güçlüdür. Ruby'de sadece kendiniz uygulayabilirsiniz:
# 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
Ve ne biliyorsunuz: bu çekirdek kütüphanede zaten mevcut File.open
. Ancak, kendi kodunuzda da kullanabileceğiniz, her türlü kaynak temizliğini ( using
C # 'da) veya işlemleri ya da aklınıza gelebilecek her şeyi uygulamak için kullanabileceğiniz genel bir kalıptır .
Kaynağın edinilmesi ve serbest bırakılması durumunda, bunun işe yaramadığı tek durum programın farklı bölümlerine dağıtılır. Ancak, örneğinizde olduğu gibi yerelleştirilmişse, bu kaynak bloklarını kolayca kullanabilirsiniz.
BTW: modern C # ' using
da aslında gereksizdir, çünkü Ruby tarzı kaynak bloklarını kendiniz uygulayabilirsiniz:
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
blok içinde olmasını istersiniz .