Top > Ruby > 入出力


コマンドライン引数

外部から情報を入力する方法として、コマンドライン引数があります。 Rubyを起動した時に、コマンドライン上で同時に指定された文字列のことであり、 定数ARGVを用いて取り出すことができます。引数は、複数指定することができます。 ARGVは配列と呼ばれるオブジェクトになっており、shiftメソッドでその引数になっている 文字列を1つずつ取り出すことができる

テストスクリプト

argv.rb
  0
  1
  2
while foo = ARGV.shift
  puts foo
end

このスクリプトを、次のように実行します。

% ruby argv.rb foo0 foo1 foo2

結果は、下記のようになります。

foo0
foo1
foo2

解説

shiftメソッドは、1, 2, 3回と実行する度に「foo0」「foo1」「foo2」という文字列を返し、 それを変数 foo に代入し、出力しています。 4回目にARGV.shiftを実行した時は、値nilが返ってくるため、 ここでこのループが終了し、スクリプトが終了します。

ところで、コマンドライン引数に似た起動オプションというものがあります。 先ほどのスクリプトを下記のように実行します。

% ruby -Ke -d argv.rb foo0 foo1 foo2

結果は、変わりません。

ここにある -Ke や -d はRubyインタプリタに対しての指示である起動オプションとなります。 今回の場合、

  • -Ke : 文字コードの種類(日本語EUC)
  • -d : デバッグモード を指定しています。
ポイント
最初に - で始まらない引数がスクリプト名。
それより前はRubyの起動オプション、それより後はスクリプトへの引数

Ruby にどんな起動オプションがあるかは、下記を実行すれば調べることができます。

% ruby --help

出力関数 print

今まで、標準出力といえば puts しか紹介しませんでしたが、 ここで print を紹介します。printは、puts と同様に表示用のメソッドですが、 puts との違いは、

  • 文字列の末尾に改行を付けない
  • 改行を行う場合は「\n」という改行を表す特殊文字を使用

です。 つまり、「print "foo\n"」と「puts "foo"」は同じ動作をします。 ただし、厳密には puts は文字列の末尾に\nが付いていたら、 改行を追加しないという違いがあります。

また、

print "foo", "bar", "baz\n"

は、

foobarbaz[改行]

となります。つまり、

puts "foo" + "bar" + "baz"

とほぼ同じ動作をします。

キーボードからの入力

テストスクリプト

gets.rb
  0
  1
foo = gets
print "入力したのは", foo, "です。\n"

このスクリプトを、次のように実行します。

% ruby gets.rb

結果は、下記のようになります。

% ruby gets.rb
asdf   (キーボードから入力し、Enter キーを押す)
入力したのはasdf
です。

解説

print 文を用いて表示しましたが、asdf の後で改行されてしまいます。 これは、ユーザーが「asdf」と入力した後に Enter キーを押下した際、 この改行文字まで gets が拾い上げてしまうからです。 この改行を取るには、.chomp というメソッドを使用します。

gets_improve.rb
  0
  1
foo = gets
print "入力したのは", foo.chomp, "です。\n"

ファイルからの入力 open

テストスクリプト

cat.rb (その1)
  0
  1
  2
  3
  4
  5
  6
# Unix 系での cat コマンドと同等の動作(ファイルを全て表示)
file_name = ARGV.shift     # ファイル名取得
f = open(file_name)        # ファイルを開く
while line = f.gets        # 1 行読み込む
  print line               # 読み込んだ 1 行を表示
end
f.close                    # ファイルを閉じる
cat.rb (その2)
  0
  1
  2
  3
  4
  5
file_name = ARGV.shift
open(file_namae) do |f|
  while line = f.gets
    print line
  end
end
cat.rb (その3)
  0
  1
  2
  3
file_name = ARGV.shift
File.foreach(file_name) do |line|
  print line
end

解説

cat.rb (その1)
open関数の戻り値は、引数で指定されたファイルの内容を表すオブジェクト、 「IOオブジェクト」である。openで開いたファイルは、処理が完了したら 必ず close メソッドで閉じなければなりません。
ファイルから1行読み込むには、gets メソッドを使用します。 最後まで読み終わったら、nilを返します。条件が nil になるため、 while 文を終了し、このスクリプトは終了します。
cat.rb (その2)
「open (file_name) do |f| ・・・end」という構文は、ファイルを読む際の 基本的なスタイルです。do・・・end で囲まれた部分を open メソッドに伴う ブロックと言い、「|」 で挟まれた変数 f をブロックパラメータと言います。 ここでは、open で得られた IO オブジェクトが自動的に f に代入されている。
また、open が終わるときに、自動的に f.close が実行されます。
cat.rb (その3)
File.foreach メソッドは、ファイルのopen、各行の読み込み、ファイルのclose を、一気に行ってくれます。File というのはクラスであり、 File.foreach のようにクラスに定義されたメソッドを「クラスメソッド」と言います。

参考(Unix系 'cat' コマンドのソース)

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 
 
 
 
-
|
|
|
|
!
 
 
-
|
|
|
-
|
|
|
|
-
|
|
|
-
|
|
!
!
!
|
|
!
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
void cat_it(FILE *fp)
{
  char buf[BUFSIZ];
 
  while(fgets(buf, sizeof(buf), fp))
    fputs(buf, stdout);
}
 
int main(int argc, char **argv)
{
  if(argc < 2)
    cat_it(stdin);
  else
  {
    int i;
    FILE *fp;
 
    for(i = 1;argv[i];++i)
    {
      if(!(fp = fopen(argv[i], "r")))
        fprintf(stderr, "mycat: %s: %s\n", argv[i], strerror(errno));
      else
      {
        cat_it(fp);
        fclose(fp);
      }
    }
  }
 
  return 0;
}

文字コード変換

テストスクリプト

  0
  1
  2
  3
  4
#!/usr/bin/ruby
require "kconv"
while line = ARGF.gets
  print Kconv.tosjis(line)
end

解説

require とは、外部ファイルを読み込む命令です。C 言語で言うところの #include です。 ここでは、Kconv というオブジェクトが kconv.rb というファイルに定義されているので、それを使用します。Ruby には様々なプログラムがあらかじめ用意されていますので、必要に応じて require で読み込み、使用することができます。

Kconv は、文字コードを変換するオブジェクトです。
ARGF は、ARGV と似ているのですが、引数をファイル名と解釈し、それらを仮想IOオブジェクトとして使用することを可能にしています。


リロード   凍結解除 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Mon, 03 Jun 2019 14:37:49 UTC (2087d)