예, ensure
코드가 항상 평가되도록합니다. 이것이 바로라는 이유 ensure
입니다. 따라서 Java 및 C #과 같습니다 finally
.
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
. 또한 예외 처리 코드에서 예외를 검사 할 수없는 변수를 제외 할 수도 있습니다. (글로벌 예외 변수를 사용하여 가장 최근에 발생한 예외에 액세스 할 수 있지만 약간 해킹입니다.) 예외 클래스를 제외하고 상속 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
루비는 실제로 Microsoft의 대제사장이 산에서 내려 와서 컴파일러를 자비 롭게 바꿀 때까지 기다릴 필요가 없을 정도로 강력하다는 점을 제외하면 C # 의 블록 과 비슷 합니다. 루비에서는 직접 구현할 수 있습니다.
# 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
. 그러나 모든 종류의 리소스 정리 ( using
C #에서 la ) 또는 트랜잭션 또는 생각할 수있는 모든 것을 구현하기 위해 자신의 코드에서도 사용할 수있는 일반적인 패턴 입니다.
리소스를 확보하고 해제하는 것이 프로그램의 다른 부분에 분산되어있는 경우 이것이 작동하지 않는 유일한 경우입니다. 그러나 예제와 같이 현지화 된 경우 이러한 리소스 블록을 쉽게 사용할 수 있습니다.
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
블록 내부에 있기를 바랍니다 .