コマンド起動

ファイルへの書き込みのかわりにコマンドを起動して、そこに データを渡してみよう。

請求書払いへの変更

sushi.rbでは、請求金額を画面表示していた。これ を郵送(電子メイルだが)するようにしてみよう。これには、結果表示していた

print "おあいそでガス\n"
printf "全部で %d 円でガス。まいどっ\n", sum*1.05

の部分の出力先を変えるだけで良い。

電子メイルを送るためには、Mail コマンドを利用する。 Mail コマンドは

% Mail -s "サブジェクト" 宛先アドレス

のように起動すると、指定した「サブジェクト」のメイルを 「宛先アドレス」宛に送ってくれる。ただし、電子メイルでは 漢字コードとしてJISコードを利用しなければならない。101教室のRubyプログラ ム環境ではEUCコードを利用しているので、これをJISコードに変換してMailコマ ンドに渡す必要がある。

漢字コードの変換

Rubyには漢字コードを変換してくれるモジュール(プログラムの部品)がつい ている。ある漢字(日本語)文字列の文字コードを変換するには Kconv モジュー ルを利用する。使い方は以下の通り。

require 'kconv'			# プログラムの先頭付近に置く

 :

jis_string = Kconv::tojis(old_string)	# JISに変換
euc_string = Kconv::toeuc(old_string)   # EUCに変換
sjis_string = Kconv::tosjis(old_string) # SJISに変換

sushi.rbプログラムの修正

出力をファイルではなくコマンドにしてみよう。元のプログラムで

print "おあいそでガス\n"
printf "全部で %d 円でガス。まいどっ\n", sum*1.05

となっていた部分を、ファイルへの書き出しに変更する場合は

open("price.out", "w") do |pr|
  pr.print "おあいそでガス\n"
  pr.printf "全部で %d 円でガス。まいどっ\n", sum*1.05
end

とすれば良い。これをメイル送信コマンドに変更するには、開くファイル名 のところをコマンド名に変えてさらに "| " を前置すれば良い。 たとえば以下のようになる。

require 'kconv'
print "どの宛先に送る(間違っちゃだめよ!)?: "
address = gets.chomp!			  # メイルアドレスを入力
command = "| Mail -s 'Price' " + address  # Mail -s 'Price' 宛先アドレス
open(command, "w") do |mail|
  mail.print Kconv::tojis("おあいそでガス\n")
  message = sprintf "全部で %d 円でガス。まいどっ\n", sum*1.05
  mail.print Kconv::tojis(message)
end

リスト中で利用しているsprintfは、printfに 似ているが、結果を出力するのではなく、「文字列」として返す。これを message 変数に保存しておいて、それを次の行でJISコードに変換 し、さらにそれをMailコマンドに送出している。

完成したプログラムは次のようになる。
sushi2.rb

#!/usr/koeki/bin/ruby

require 'kconv'

sum = 0
menu = []
name = []
price = []
i = 1

open("price.txt", "r") do |neta| # price.txtを読み込みモードで開く
  while line = neta.gets	 # ファイルから1行ずつ読む
    if /(\w+)\s+(\d+)円/e =~ line # (数字)円 というパターンがあれば
      menu[i]  = $1		 # $1 は商品名
      price[i] = $2.to_i	 # $2 が「数字」に当てはまるので整数化
      printf "%3d %s", i, line	 # 商品番号と、読み込んだ行を画面表示
    end
    i += 1
  end
end

while true
  print "御注文は(番号で入れてね、q で終了)?: "
  line=gets.chomp!		# ユーザの入力を line に入れる
  if line == "q"		# 入力が "q" なら
    break			# 終了
  end
  number = line.to_i		# 整数(メニュー番号)にする
  if number < 1 || number >= i
    puts "そんなメニューねぇでガス"
    redo
  end
  printf "はぁ〜い、「%s」一丁\n", menu[number]
  sum += price[number]
end

print "どの宛先に送る(間違っちゃだめよ!)?: "
address = gets.chomp!			  # メイルアドレスを入力
command = "| Mail -s 'Price' " + address  # Mail -s 'Price' 宛先アドレス
open(command, "w") do |mail|
  mail.print Kconv::tojis("おあいそでガス\n")
  message = sprintf "全部で %d 円でガス。まいどっ\n", sum*1.05
  mail.print Kconv::tojis(message)
end

ファイル入出力の処理例