カレンダープログラムが一応できましたが、このプログラムでは、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);