2017-12-29 56 views
0

현재 ARGV.gets를 사용하여 명령 줄에서 사용자 입력을 캡처하고 있습니다. Ctrl-D가 스크립트를 종료하도록 허용하고 싶지만 Signal.trap 또는 오류 처리를 통해이를 수행하는 방법을 모릅니다. 나는 Ctrl-D와 같은 것을위한 트랩 코드의 목록을 찾으려고 노력했지만, 내가 찾던 것을 찾을 수 없었다. 마찬가지로, Ctrl-D가 예외를 발생시키지 않으므로 예외 구조는 작동하지 않습니다. Ctrl-D 또는 다른 방법으로이를 탐지하는 트랩 코드가 있습니까? 나는 현재 트래핑으로 Ctrl-C를 감지 할 수 있어요 예를 들어ARGF가있는 Ruby 스크립트의 Ctrl-D 트랩

... ...

# Trap ^C 
Signal.trap("INT") { 
    # Do something 
    exit 
} 

또는 오류 처리 ... 그러나

def get_input 
    input = ARGF.gets 
    input.strip! 
    rescue SystemExit, Interrupt => e 
    # If we get here, Ctrl-C was encountered 
end 

, 나는 Ctrl-D를 잡아 내지 못했습니다.

답변

1

ARGF 스트림의 특별한 경우입니다. Ctrl + D은 입력의 끝 부분입니다.

이것을 염두에두고 ARGF.eof?을 사용하십시오. Link to documentation

+0

저는 그것이 콘솔이 아닌 파일 스트림의 경우에만 유효하다고 생각합니다. – gangelo

0

유스 케이스가 확실하지 않지만 스크립트를 종료하기 전에 무엇인가를하려고한다고 가정합니다. 그렇다면 최상의 방법은 아마도 신호 트래핑보다 약간 쉬울 것입니다. KernelModule 실제로 프로그램이 실제로 종료되기 바로 전에 실행될 #at_exit 메서드를 제공합니다.

사용법 : (Kernel#at_exit Docs에서)는

def do_at_exit(str1) 
    at_exit { print str1 } 
end 
at_exit { puts "cruel world" } 
do_at_exit("goodbye ") 
exit 

"생산"

goodbye cruel world 

당신이 역순으로 실행됩니다 여러 핸들러를 정의 할 수 있습니다 볼 수있는 경우 프로그램이 종료됩니다. Kernel 이후

는 당신이 ObjectSpace.define_finalizer 좀 걸릴 수 있습니다

더 구체적인 Object 기반의 구현 또한
p = People.new 
p.send(:at_exit, &->{puts "We are leaving"}) 
# We are leaving 
# The People have left 

Object 특성뿐만 아니라 같은

class People 
    at_exit {puts "The #{self.name} have left"} 
end 
exit 
# The People have left 

또는 인스턴스를 처리 할 수 ​​Object에 포함되어 있습니다 . 사용의

예 :

class Person 
    def self.finalize(name) 
    proc {puts "Goodbye Cruel World -#{name}"} 
    end 
    def initialize(name) 
    @name = name 
    ObjectSpace.define_finalizer(self, self.class.finalize(@name)) 
    end 
end 

사용법 :

p = Person.new("engineersmnky") 
exit 
# Goodbye Cruel World -engineersmnky 

Object뿐만 아니라 (임시 객체에 대한 크지 않은 쓰레기 수집 할 때 특별히가 발광이로 원하는 것을하지 않을 수 있습니다)하지만 전체 응용 프로그램 전체에 존재해야하는 객체가 있으면 at_exit와 비슷하게 사용할 수 있습니다.예를 들어 당신이 Person이 gc'd 때문에 p2에 대한 정의 종료자를 해고 그러나 프로그램이 아직 종료되지 않은 볼 수 있듯이

# requiring WeakRef to allow garbage collection 
# See: https://ruby-doc.org/stdlib-2.3.3/libdoc/weakref/rdoc/WeakRef.html 
require 'weakref' # 
p1 = Person.new("Engineer") 
p2 = Person.new("Engineer's Monkey") 
p2 = WeakRef.new(p2) 
GC.start # just for this example 
# Goodbye Cruel World -Engineer's Monkey 
#=> nil 
p2 
#=> WeakRef::RefError: Invalid Reference - probably recycled 
exit 
# Goodbye Cruel World -Engineer 

. p1의 파이널 라이저는 응용 프로그램 전체에서 해당 참조를 유지했기 때문에 종료 될 때까지 대기했습니다.