プログラミング工房 > Ruby > Tips > 

小ネタいろいろ

コマンドライン引数の取得
ファイル分割(スクリプト挿入)
確実にキーボードからの入力を取得する


確実にキーボードからの入力を取得する


 Rubyには標準入力から1行のデータを得るためのメソッドとして「gets」というのがありますが、このメソッドをレシーバ指定なしで呼び出す("hoge.gets"ではなく"gets"だけの形式で呼び出す)場合、必ずしもキーボードからの入力を待つ動作になるとは限りません。getsメソッドで確実にそのようにしたい場合は、レシーバに「STDIN」を指定し"STDIN.gets"という形で呼び出してやる必要があります。

 Kernelモジュールのgetsメソッドは、標準入力またはAGRVに指定されたファイルをつなげたデータから1行読み込む機能を持っており、レシーバ指定なしでお手軽に呼び出せますが、コマンドライン引数が指定されていたり$stdinが変更されていたりすると、データの取得元はキーボードにはなりません。確実にキーボードからユーザの入力をするには、デフォルトの標準入力を表すSTDINのgetsメソッドを使います。

(2007/07/17追記)

 ただしスクリプトを実行するruby自体の標準入力がリダイレクトされている時には、STDINもキーボードから変更されてしまっているためgetsやgetcなどのメソッドでキーボードからの入力を取得することはできません。

 このような場合Windowsではmsvcrt.dllの_getch関数で入力データを取得する方法があります。以下のスクリプトでは、無限ループ中で繰り返し_getch関数を実行し入力されたデータを記録しつつ、改行が入力されたらループを抜け入力データ全体を表示する処理を行っています。


require 'Win32API'
getch = Win32API.new('msvcrt','_getch',[],'l')

str =  ''
while true
   ch = getch.call
   if ch == 13
      break
   end
   str += ch.chr
   print ch.chr
end
puts "\n入力された文字列:" + str

 ちなみにキーの種類に関係なく何らかのキーが押されるまでスクリプトの実行をストップしたいという場合は、_kbhitという関数が利用できます。以下のスクリプトでは、無限ループ中で繰り返し_kbhit関数を実行しキー入力があり次第ループを抜ける処理を行っています。


require 'Win32API'
kbhit = Win32API.new('msvcrt','_kbhit',[],'l')

print '続行するには何かキーを押してください'
while true
   if kbhit.call != 0
      break
   end
end
puts "\nキーが押されました"


コマンドライン引数の取得


 スクリプト実行時に渡されたコマンドライン引数は、定義済みの変数ARGVに配列として格納される。個々の引数はインデックスで指定する各要素から取得でき、引数の数はlengthメソッドを実行することで取得できる。

 Rubyインタプリタに対する引数は、実行されるスクリプト名を含め、ARGVには格納されない。


ファイル分割(スクリプト挿入)


 Rubyで別ファイルに保存したスクリプトを読み込んで実行するには、loadまたはrequireを使う。

 loadは単純に指定されたファイルを読み込んで実行するだけだが、requireはひとつのプログラム内では同じファイルに対して何回実行されても最初の1回のみ有効。