2017-12-29 56 views
0

現在、ARGV.getsを使用してコマンドラインからユーザー入力を取得しています。 Ctrl + Dでスクリプトを終了させたいのですが、Signal.trapやエラー処理を使ってこれを行う方法がわかりません。私はCtrl-Dのようなもののためのトラップコードのリストを見つけようとしましたが、私が探していたものを見つけることができませんでした。同様に、Ctrl-Dは例外を発生させないため、Exceptionレスキューは機能しません。 Ctrl-Dやこれを検出する他の方法のトラップコードはありますか?例えばARGFを使用したRubyスクリプトでのCtrl-Dのトラップ

... は、私は現在...

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

やエラー処理をトラップしてはCtrl-Cを検出することができるよ...

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ましたが、プログラムがまだ終了していないため、例

# 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 

あなたがp2のために定義されたファイナライザを見ることができるように解雇しました。 p1のファイナライザは、アプリケーション全体で参照を保持していたため、終了するまで待っていました。

関連する問題