2001/11/19

前回につづき cal.pl の勉強を続けますが、その前に訂正および簡単な スクリプトの作成を復習として行います。

前回、スカラーを並べたもの、例えば (3, 10, 2, 15) を配列と呼ぶと説明しましたが、 「リスト」と呼ぶのが普通のようです。 「入門Perl」(河野真治著)では「ベクタ」という表現も使われていました。 「配列」はリストを値に持つ変数のことをいうことにします。 なお、リストを囲むかっこ()は必ずしも必要ではありません。 あいまいさがなければ省略してかまいません。例えば関数の引数は リストの形であたえますが、次のどちらで書いても普通は同じです。 ただ式の中のかっこと混乱する場合ははっきり囲む必要があります。 次の2行を比較してみて下さい (kakko.pl)

前回変数の名前にはアルファベットと下線のみを使うと書きましたが これに数字も追加して下さい。忘れていました。それからもちろんこれらは 半角のものです。全角の文字を使ってはいけません。また先頭の文字は 下線や数字でなくアルファベットを使って下さい。例えば「$1」などは すでに予約されているので使ってはいけません。

次に前回習ったことを使って簡単なスクリプトを書いてみます。

まず以下のスクリプト(mycalc1.pl)を眺めて、これがどんな働きをするか考えてみて下さい:


#!/usr/bin/perl
die "Usage: jperl mycalc1.pl num1 num2\n" unless @ARGV == 2;
($num1, $num2) = @ARGV;
$product = $num1 * $num2;
print "$num1 * $num2 = $product\n";

簡単ですね。2つの数を与えてその積を計算するプログラムです。

I:\www>jperl mycalc1.pl 5 3
5 * 3 = 15


かけ算だけでは面白くないので次のようなスクリプト(mycalc2.pl)を作りましょう。


#!/usr/bin/jperl
die "Usage: jperl mycalc2.pl 計算式\n" if @ARGV == 0;
$string = join(' ', @ARGV);
$value = eval($string);
print "$string = $value\n";

ここでは join という関数と eval という関数が出てきます。
join は2つのパラメータ(引数)をとります。最初の引数は文字列で、2番目の文字列は リスト(配列)です。 指定した配列の隣り合う要素の間に最初の引数で指定した文字列をはさんでつなぎ、 できた文字列を値として返します。上の例ではコマンドライン上で指定した 引数たちを空白文字(スペース)ではさんでつなぎ、文字列を作っています。その文字列が $string という変数に格納されます。
eval は引数で与えた文字列を「式」と解釈してその値を返します。 上ではその値が $value に格納されます。

それでは実行してみましょう。

I:\www>jperl mycalc2.pl
Usage: jperl mycalc2.pl 計算式

I:\www>jperl mycalc2.pl 5 + 3
5 + 3 = 8

I:\www>jperl mycalc2.pl sqrt(2)
sqrt(2) = 1.414213562373095146

I:\www>jperl mycalc2.pl 3/2 + 1/4
3/2 + 1/4 = 1.75

I:\www>jperl mycalc2.pl (3 + 4) / 4
(3 + 4) / 4 = 1.75

I:\www>jperl mycalc2.pl 3 * 5
3 ???ごちゃごちゃ??? 5 =

なかなかうまく計算してくれますが「 3 * 5 」のときはなんだか変ですね。 それは「*」がコマンドライン上で特別な意味をもっているからなのです。 このような場合は引数全体を二重引用符号で囲んでみて下さい。 (なお、「*」以外にも色々特別な意味をもつ記号があります。) --- と書きましたが Windows2000 ではこれ、大丈夫ですね。下の部分でも このようにならないところがあるようです。(授業後のコメント)

I:\www>jperl mycalc2.pl "3 * 5"
3 * 5 = 15

このスクリプトを使えばいろんな演算子のはたらきを調べることができます。 試してみて下さい。

I:\www>jperl mycalc2.pl "2 ** 10"
2 ** 10 = 1024

I:\www>jperl mycalc2.pl "5 > 3"
5 > 3 = 1

I:\www>jperl mycalc2.pl "5 < 3"
5 < 3 = 0

I:\www>jperl mycalc2.pl "5 && 3"
5 && 3 = 3

I:\www>jperl mycalc2.pl "5 || 3"
5 || 3 = 5

I:\www>jperl mycalc2.pl "0 || 3"
0 || 3 = 3

それでは前回のつづきで cal.pl の解読をすませてしまいましょう。

Perl入門

「Perlの第1歩」



今回の課題

以下の課題のうち少なくとも一つを各自のHP上に発表して下さい。

課題1:Zeller の公式を自分で発見できますか? どう考えたら このような公式を見つけだすことができるでしょう。色々考えたことを ホームページに書いてみて下さい。

課題2:日付を与えてその曜日を表示させるプログラムを作りなさい。 スクリプト自身が読めるようにして下さい。

I:\www>jperl youbi.pl 2001 11 12
2001年11月12日は月曜日です


[2001/11/22]
何人かの方から、上の課題2が難しいというメールを貰いました。 ヒントをだします。

まずそのスクリプトがどんな機能を持つ部分から構成されるべきか 考えてみます。

  1. まず、指定した「年」「月」「日」の3つをそれぞれ 対応する変数に格納します。
  2. 1 で得られた状態をもとに、「曜日」を数値として計算します。
  3. 2 で得られた数値から「日月〜土」の文字を得ます。
  4. 最終的な出力を行います。

まず、cal.pl の内容を新しいファイル youbi.pl に貼り付けます。 カレンダー表示のための部分(その月の日数を求める部分、カレンダーの タイトルを出力する部分、カレンダーの曜日を出力する部分、カレンダーの 本体部分)はばっさり削除してしまってかまいません。 ただ削除したものを復活させる必要があるかもしれないし、削除しすぎる おそれがあるので、本当に消すのではなく行頭に「#」を付けてコメント にしてしまえばいいでしょう。

上のステップ1に対応させるためには引数を2から3に変更する必要が あります。日にちの値を格納する変数は $day とでもしてください。

ちゃんと値が格納できたかどうかそれらをprintを用いて表示させてみて下さい (これだけなら曜日を求める関数も不要ですが、特に削除する必要は ありません)。 これから先ができなかった場合は、これでもいいですから、自分のページに 載せてください。

I:\www>jperl youbi.pl 2001 11 12
2001年11月12日

上ができたら次はステップ2です。考えられる方法は2つあります。 まずはもともとの getweek をそのまま使って、その月の1日の 曜日を計算し、その値と $day から該当する日にちの曜日を求める方法。 もうひとつは getweek を書き直して3変数の関数にすること。 どちらも同じようなものですので、好きな方法を用いてください。 それでは曜日も(数値で)出力するように書き換えます。 曜日がずれていないか確かめてください。

I:\www>jperl youbi.pl 2001 11 12
2001年11月12日は1曜日です

ステップ3では数値から曜日を表す漢字を得ます。 これには ('日', '月', '火', '水', '木', '金', '土')という リストを用意し、その要素を番号の指定により得ればよいでしょう。 ここまでできればもうほとんど出来上がりですね。 がんばって仕上げてください。 わからないところはメールで質問してください。 ただ、今出張中ですので夜までメールのチェックができません。あしからず。