カレンダ−・プログラムの改良(1)−パラメータの入力

カレンダープログラムが一応できましたが、このプログラムでは、2002年4月のカレンダーしか表示できません。それでは、まったくプログラムらしくないので、コマンドラインから $ calendar.pl [year] [month] というようにパラメータを入れて、カレンダーを表示するようにしましょう。

コマンドに渡されるパラメータは、Perl では @ARGV という配列に格納されることになっていますから、

#!/usr/bin/perl
#
# calendar01.pl - perl calendar version 0.1
#

$year = $ARGV[0];
$month = $ARGV[1];
としてやれば、インプットした年と月のカレンダーが示されます。

しかし、calendar01.perl の使い方がわからずに、パラメータを入れないでしまう場合があります。そんな時のために

if($ARGV[0] eq ""){
    print "Input year and month.\n";
    exit(0);
    }
というコメントをいれてやると親切でしょう。eq は == と同じ、ne は != と同じです。文字列同士の比較の場合は eq や ne を使うほうが分かりやすいかと思い、これを使ってみました。

それでも、年だけ入れて、月を入れ忘れる時もあります。その場合も、月を入れるようにメッセージを出すといいでしょう。そのためには、

if($ARGV[0] eq ""){
    print "Input year and month.\n";
    exit(0);
    }
elsif($ARGV[1] eq ""){
    print "Input month, too.\n";
    exit(0);
    }
としてやれば良いのです。if(....){....}else{....} は「もし....ならば....せよ。さもなければ....せよ」という意味で、else 以降でパラメータに価が入っていた場合の処理を指定しています。

しかし、人間のすることには間違いがつきもので、月の指定に 0 や 13 というのを入れた場合「間違っています」と伝えるようにしておくのも必要でしょう。

if($month < 1 or $month > 12){
    print "Month is out of range (1 - 12).\n";
    exit(0);
    }

$ calendar01.pl 2002 12 と入れなければならないのに、$ calendar01.pl 2002-12 と入れる場合があるかもしれません。このような入力をも受けつけるためには、ちょっとしたテクニックが必要です。これを試すために、次のようなテスト用プログラムを書いてみました。

#!/usr/bin/perl
#
# split.test
#

@parameters = split /\D/, $ARGV[0];
my $i = 1;
for $parameter (@parameters){
    print "Parameter $i: $parameter\n";
    $i++;
    }
このプログラムに 2002-12 というパラメータを渡してやると、次のような結果が返ってきます。
Parameter 1: 2002
Parameter 2: 12
そうしたら、
$year = $parameters[0];
$month = $parameters[1];
という行を加えてやれば、このようなパラメータも解析して、年と月を取りだせることがわかります。

ここでは、split というファンクションを使っています。split は、ある文字列を // で囲んだ文字で区切り、それを配列にいれてくれる便利な関数です。Perl の特徴は、文字列の操作を簡単にできることにあり、これもその一つの例です。

@parameters = split /\D/, $ARGV[0];
この式には「$ARGV[0] を、数字でない文字で区切って、それを @parameters に格納する」という仕事をさせています。// で囲まれた \D は split 関数で使うことのできるメタキャラクタのひとつで「0 - 9 でない文字」を表しています。

my $i = 1;
for $parameter (@parameters){
    print "Parameter $i: $parameter\n";
    $i++;
    }
テストプログラムの for $parameter (@parameters){....} も、便利な書式で「配列 @parameters の要素を 0番目から最後まで取り出し、$parameter に入れる」という意味です。

次は、改良したメインルーチンの最初の部分です。calendar.pl のメインルーチンと入れ換えて実行してみてください。$ ./calendar01.pl のあとに 2002-12 としても、2002,12 でも 2002/12 であっても同じ年月のカレンダーを表示してくれます。

if($ARGV[0] eq ""){
    print "Input year and month.\n";
    exit(0);
    }
if($ARGV[1] eq ""){
    @parameters = split /\D/, $ARGV[0];
    if($parameters[1] eq ""){
        print "Input year and month.\n";
        exit(0);
        }
    else{
        $year = $parameters[0];
        $month = $parameters[1];
        }
    }
else{
    $year = $ARGV[0];
    $month = $ARGV[1];
    }
if($month < 1 or $month > 12){
    print "Month is out of range.\n";
    exit(0);
    }
&find_first_last();
&show_a_month();
exit(0);

[前のぺ−ジ] [目次] [次のぺ−ジ]