コマンド起動

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

請求書払いへの変更

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

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

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

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

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

のように起動すると、指定した「サブジェクト」のメイルを 「宛先アドレス」宛に送ってくれる。ただし、電子メイルでは 漢字コードとしてJISコードを利用しなければならない。

情報教室のLinux環境にはmailコマンドがないため、かわりに mail.rbプログラムを保存して chmod +x して使用する。

漢字コードの変換

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

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

 :

jis_string = old_string.tojis	# JISに変換
euc_string = old_string.toeuc   # EUCに変換
sjis_string = old_string.tosjis # SJISに変換
utf8_string = old_string.toutf8 # UTF-8に変換

sushi.rbプログラムの修正

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

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

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

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

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

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

sprintfメソッドは、printfで 出力される結果を「文字列」として返すだけで実際には出力しない。これを message 変数に保存しておいて、それを次の行でJISコードに変換 し、さらにそれをMailコマンドに送出している。

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

sushi2.rb

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-

require 'kconv'                 # 漢字コード変換に利用

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

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

while true
  print "御注文は(番号で入れてね、q で終了)?: "
  line=gets.chomp!		# ユーザの入力を line に入れる
  if line == "q"		# q なら
    break			#   終了
  end
  number = line.to_i		# 整数(メニュー番号)にする
  if number < 0 || 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 "おあいそでガス\n".tojis
  message = sprintf("全部で %d 円でガス。まいどっ\n", sum)
  mail.print message.tojis
end

使用しているマシンから 電子メイルを送る設定がされている場合は 実際に送信実験してみよう。実行時には自分のメイルアドレスを入れる。

./sushi2.rb
       :
       :
 (注文を繰り返す)
       :
       :
御注文は(番号で入れてね、q で終了)?: q
どの宛先に送る(間違っちゃだめよ!)?: 自分のメイルアドレス

ファイル入出力の処理例