Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby 프로그램을 종료하는 방법

개발자로서 우리는 프로그램을 실행하는 데 너무 많은 시간을 할애하여 프로그램이 종료되는 방식을 간과하기 쉽습니다. 그리고 중요합니다! 프로그램이 종료될 때 올바르게 작동하면 관리하기가 훨씬 쉬워지고 표준 devops 도구와 함께 작동할 가능성이 높아집니다.

Ruby 프로그램을 종료하는 방법에는 여러 가지가 있습니다. 나는 그들 중 일부를 아래에 보여 주었다. 이 게시물에서 우리는 이들 각각에 대한 세부 정보와 앱이 제대로 작동하는 Unix 시민으로 만드는 데 어떻게 사용될 수 있는지 논의할 것입니다.

# You can exit by calling a method
exit
exit!
abort("She cannot take any more of this, Captain!")

# ...or by failing to catch an exception
raise("Destroyed...")
fail

# ...or by letting the program end naturally. :)

출구 코드, 그리고 당신

Linux 및 OSX에서 실행하는 모든 프로그램은 실행이 완료되면 종료 상태 코드를 반환합니다. 일반적으로 종료 코드는 표시되지 않습니다. 프로그램이 정상적으로 종료되었는지 또는 오류가 있었는지 확인하기 위해 OS에서 배후에서 사용합니다.

bash를 사용하는 경우 $?를 검사하여 방금 실행한 프로그램의 종료 코드를 볼 수 있습니다. 환경 변수. 아래 예는 실패에 대한 종료 코드와 성공에 대한 종료 코드를 보여줍니다.

% ls this-file-doesnt-exist
ls: this-file-doesnt-exist: No such file or directory
blog% echo $?
1
% ls .
bm.rb 
% echo $?
0

일반적으로 유닉스 기반 시스템의 규칙은 0이 성공을 의미한다는 것입니다. 0이 아닌 것은 실패를 의미합니다.

&&를 사용한 적이 있다면 bash에서 'operator'를 입력한 다음  상태 코드를 사용했습니다. 아래 예에서는 프로그램 A가 성공한 경우에만 프로그램 B를 실행하도록 bash에 지시합니다.

% a && b

이 트릭을 여러 가지 방법으로 사용할 수 있습니다. 예를 들어 자산을 사전 컴파일하고 CDN에 업로드할 수 있습니다.

blog% rake assets:precompile && rake cdn:upload_assets

Ruby로 종료 상태 지정

Ruby는 우리를 위해 많은 종료 상태를 처리합니다. 프로그램이 정상적으로 종료되면 "성공" 상태를 반환합니다. 잡히지 않은 예외로 인해 실패하면 "실패" 상태가 됩니다. 아래는 예외를 발생시킨 스크립트의 종료 코드입니다.

% ruby err.rb
err.rb:1:in `<main>': goodbye (RuntimeError)
tmp% echo $?
1

하지만 잡히지 않는 예외를 원하지 않는다면 어떻게 될까요? 깔끔하게 종료하고 싶지만 여전히 "실패한" 오류 코드를 반환하는 경우 어떻게 하시겠습니까? 또한 오류 메시지와 함께 사용자 정의 코드를 반환하려면 어떻게 해야 합니까?

다행히도 아주 쉽습니다. exit에 인수를 전달하기만 하면 됩니다. 기능. 인수는 부울 또는 정수일 수 있습니다. 부울이면 true는 성공을 의미합니다. 0보다 정수이면 성공을 의미합니다.

exit(true) # Exits with "success" code
exit(0) # Exits with "success" code

exit(false) # Exits with "failure" code
exit(1) # Exits with "failure" code

exit(436) # Custom failure error code

exit 방법 후드 아래에서 작동

exit 메소드는 단순히 SystemExit를 발생시킵니다. 예외. 잡히지 않으면 다른 잡히지 않는 예외와 마찬가지로 프로그램이 중단됩니다. 정말 멋지지만  몇 가지 흥미로운 결과가 있습니다.

모든 SystemExit 예외를 삼키면 exit 메서드가 중단됩니다. 아래 예에서 이것을 보여주었습니다.

begin
  exit 100
rescue SystemExit => e
  puts "Tried to exit with status #{ e.status }"
end

puts "...but it never exited, because we swallowed the exception"

# Outputs:
# Tried to exit with status 100
# ...but it never exited, because we swallowed the exception

이것이 Exception을 절대 구하지 않는 또 다른 이유입니다. . SystemExit이기 때문에 Exception에서 상속 , Exception 삼키기 종료가 중단됩니다.

begin
  exit
rescue Exception # never do this
  puts "I just broke the exit function!"
end

사람이 읽을 수 있는 오류 메시지

종료 코드는 기계에 적합하지만 우리 인간은 종종 약간의 설명 텍스트를 선호합니다. 다행히 OS는 특히 오류 메시지와 같은 출력 스트림을 제공합니다. 예, STDERR에 대해 이야기하고 있습니다.

IO 개체에 쓰는 것처럼 STDERR에 쓸 수 있습니다. 아래 예에서는 오류 메시지를 작성하고 "오류" 상태로 종료합니다.

STDERR.puts("ABORTED! You forgot to BAR the BAZ")
exit(false)

이것은 Ruby이므로 stdout에 작성하고 오류 코드로 종료하는 보다 간결한 방법이 있습니다. abort을 사용하세요. 방법.

# Write the message to STDERR and exit with an error status code.
abort("ABORTED! You forgot to BAR the BAZ")

at_exit를 통한 콜백

Ruby를 사용하면 프로그램이 종료될 때마다 호출할 수 있는 핸들러를 등록할 수 있습니다. 둘 이상이 있을 수 있습니다. 등록된 순서와 반대 순서로 호출됩니다. 모양은 다음과 같습니다.

at_exit do 
  puts "handler 1"
end

at_exit do 
  puts "handler 2"
end

# Outputs "handler2\nhandler1" on exit

종료 핸들러는 종료 코드를 재정의할 수 있습니다. 핸들러 내에서 exit를 호출하여 이를 수행합니다. 이것이 무한 루프를 일으키는 것처럼 보이지만 그렇지 않습니다. :)

at_exit do 
  exit 100
end

exit 0

# This program exits with a code of 100

콜백을 호출하지 않고 종료하려면 exit!를 통해 종료할 수 있습니다. 방법. 그러나 이러한 콜백에 의존하는 gem 또는 기타 타사 코드가 있는 경우 문제가 발생할 수 있음을 명심하십시오.

흥미로운 부분

많은 라이브러리가 at_exit를 사용하는 것으로 나타났습니다. 독창적이고 일부는 해키 방식으로 말할 수 있습니다. 예를 들어, Sinatra는 at_exit를 사용합니다. 웹 앱을 부팅하는 방법으로 에 연결합니다. 이렇게 하면 서버를 시작하기 전에 모든 코드가 로드되었는지 확인할 수 있습니다. 다음과 같습니다.

module Sinatra
  class Application < Base

   ...

  at_exit { Application.run! if $!.nil? && Application.run? }
end

이에 대한 훌륭한 게시물이 Arkeny 블로그에 있습니다. 우리는 at_exit를 학대하고 있습니까?