ktermにおいてrubyプログラムを実行する際、
irsv{学籍番号}%./prog.rb
とか
irsv{学籍番号}%ruby prog.rb
と入力した。
特殊な方法として、
irsv{学籍番号}%ruby prog.rb data.txt
のようにプログラム名の後ろにファイル名を指定すると、そのファイルを読み込ませ、プログラムの中で取り扱うことができた。前期の正規表現の授業で取り上げたが覚えているだろうか。
ktermからプログラムを実行する際に、プログラム名の後ろに値を指定することで、その値をプログラム内で使用することができる。前期はファイル名のみを指定したが、以下のように数値を指定することもできる。
irsv{学籍番号}%ruby prog.rb 100 200 300
ktermからプログラムを実行する際に上記のように与えた値のことを引数(ひきすう)という。Rubyでは、与えた引数は自動的にARGVという配列変数に代入される。
上記の例では100、200、300という引数が与えられており、配列変数のARGVのインデックス0、1、2にそれぞれ
ARGV[0] = "100"
ARGV[1] = "200"
ARGV[2] = "300"
のように代入される。いずれも文字列であることに注意する必要がある。なお100 200 300の間はスペースのみでありカンマ等はないことに注意せよ。
これを利用すると、プログラムを起動する際に与えた値に基づいて動作を決定させることができる。
ktermからプログラムを実行する際に引数を指定すると、ARGVという配列変数に代入される
1からユーザが指定した任意の値までの足し算を行うプログラムを書いてみよう。これまでは、プログラム実行後に「好きな数字を入力してください」と表示し、キーボードから入力された値をgetsメソッドで取得するという以下のようなプログラムを書いてきた(sum-gets.rb)。
#!/usr/koeki/bin/ruby sum = 0 print "好きな数字を入力してください" goal = gets.chomp!.to_i 1.upto(goal) do |i| sum += i end printf ("1から%dまでの合計は%dです\n",goal, sum)
これをARGVを使用して書き換えることを考えてみよう。仮に30までの合計を求める場合、ktermでプログラムを実行する際に以下のように引数を与える必要がある(プログラム名はsum-ARGV.rbとする)
irsv{学籍番号}%ruby sum-ARGV.rb 30
プログラムは以下の通りとなる。ktermにおけるプログラム実行時に与えた引数である30はARGV[0]に代入される。文字列として取り扱われるため、goal = ARGV[0].to_iとし、整数に変換してからgoalに代入している。
#!/usr/koeki/bin/ruby sum = 0 goal = ARGV[0].to_i 1.upto(goal) do |i| sum += i end printf ("1から%dまでの合計は%dです\n",goal, sum)
sum-ARGV.rbを実行してみよう。実行するときに引数を与えなかった場合にはどのような結果になるだろうか。実行結果を確認した上で、なぜそのような結果になるのかを考えてみよう。
制限時間は10分。出席点は2点。提出要領は下記の通り。
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:Mewによるメールの送り方はMewコマンドを参照
sum-ARGV.rbでは、プログラム実行時に引数を与えることが、プログラムを正常に実行する上での前提条件となっている。引数を与えなければ正しく実行することができない。しかし、実行しても何も起こらないプログラムでは、ユーザーは何がおかしいのかを理解することができない。おそらく自分の実行の方法が間違っているのではなく、プログラム自体に誤りがあるのではないかと考えるはずである。この問題を解決するために、プログラムを改良してみよう。
#!/usr/koeki/bin/ruby
if ARGV[0] == nil
STDERR.print "1からプログラム起動時に指定した値までの合計を出します\n"
STDERR.print "50までの総和を出したい場合 ruby goukei-ARGV.rb 50と入力します\n"
exit(1)
end
sum = 0
goal = ARGV[0].to_i
1.upto(goal) do |i|
sum += i
end
printf ("1から%dまでの合計は%dです\n",goal, sum)
このプログラムでは上部の5行(黄色の部分)を追加している。これは1つのif文である。ifの横の条件としてARGV[0] == nilを指定している。nilとはデータがないという意味であり、ARGV[0]にデータがないということは、プログラムを実行する際に引数を与えていないということを意味する。この場合にendの前にある3行を実行する。
STDERR.printの2行:メッセージをディスプレイに出力する。このメッセージを出すことでユーザはプログラムの実行方法が間違っていたことがわかる。このプログラムに関して言えば、STDERR.printではなくprintでもよい。STDERR.printは出力先としてファイルとディスプレイのいずれも指定することができる場合に、ディスプレイを指定する際の記法である(詳細は前期のopenメソッドの回を確認しよう)。STDERR.printとすることでディスプレイに表示することを明示的に示していると考えておけばよい。
exit(1):exitはプログラムの強制終了をあらわす。このプログラムでは引数を入力せずにプログラムを実行した場合、プログラムを継続する意味がない。そこでexitを使用して強制的にプログラムを終了している。プログラムを終了させる場合、プログラムの実行がうまくいったかどうかをシステムに対して示すことができる。これを終了ステータスというが、プログラムがうまくいった場合は0を用い(exit(0))、うまくいかなかった場合は0以外とする(exit(1))決まりになっている。
以下のうちいずれかを選んで解答する。ARGVを用いて記述すること。ARGVを用いなかった場合は配点を1点マイナスとする(例えば、10点満点の問題は9点満点で採点)。
問題1(8点満点):プログラム実行時に2つの引数を与え、その値に基づいて何らかの処理を行うプログラムARGV.rbを作成せよ。自力で作ったことがわかるよう、ほかの人と重複しないような独自性の高いプログラムを作成してみよう。
問題2(10点満点):シーザー暗号とはもとの文字を○文字ずらして変換することで無意味文字つづりに変換するものである。例えば3文字ずらすというルールを設けた場合、KOEKIはNRHNLとなる。プログラムを実行する際に、もとの文字列と、何文字ずらすか、変換モードを引数として与えることで、暗号化及び復号ができるプログラムcode.rbを作成せよ。ここで暗号化とはもとの文字列を無意味文字つづりに変換することを指し、復号は無意味文字つづりからもとの文字列に変換することを指す。変換モードとして1を与えた場合は暗号化、2を与えた場合は復号ができるようにせよ。
このプログラムを作成するに当たっては文字コードについての理解が必要である。文字はすべて2進数で表現することができる。以下は半角英数字の文字コードであるASCIIコード表である。ここで大文字のAは0x41(16進数)、小文字のaは0x61(16進数)となる。0x41を0x44に変更すればAがDに変わり3文字ずらしたことになる。復号する場合は44から3を引いて41にすればよい。日本語を取り扱うのは難しいため、以下の条件で作成すればよい。
Tips:emacsでの日本語入力のオンオフはCtrl-oです
Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする
Tips:Mewによるメールの送り方はMewコマンドを参照