Perl を使おう! 第3回


[ 目次 / 前頁 / 次頁 ]

前回の宿題

自分のホームページにカウンターを入れ、perl でdateコマンドの結果を整形し year month date (week) time の形で表示しましょう。

例)

あなたは、15人目の訪問者です。
現在時刻 1996 Nov 15 (Feb) 15:00:00
こんな風にページに入れてみましょう。(これは、そのまま書いたものなので変化しません)
回答例 by yama

現在時刻をdateコマンドを使って、その表示を指定したフォーマットで出力するプログラムについては

  === begin [now.pl]===
  #!/usr/bin/perl
  chop($date =`date`);
  @date=split(/ /,$date);
  print "@date[5,1,2] ($date[0]) $date[3]\n";
(注意)dateコマンドの結果得られる文字列には改行が入っているので、まず取ります。 print の部分では、$date[5] $date[1] $date[2] は @date[5,1,2] で表されることを使いましょう。できるだけ、シンプルに!

さて、date コマンドから得られる結果は月のフォーマットは、数字にはなっていないので、yyyy/mm/dd のようなフォーマットを作るのはおかしな感じですね。 これを直すには... もう少しいろいろと、Perl について知っていた方が良さそうだ。 ということで、


Perl 言語 その2

  1. 連想配列

    連想配列は、任意のスカラー値をインデックスとして取れる配列です。
    配列変数
    連想配列変数は名前の前に%を置いて表します。 連想配列 %hai の要素を参照するのは、$hai{$key} とします。 例えば、
        $month{'Jan'}=1;
        $month{'Feb'}=2;
    
    などのように利用します。 配列全体を初期化したり、別の連想配列にコピーする際には、配列全体にアクセスする必要がありますが、Perl は連想配列に対するリテラルを持っていないので、連想配列を展開してリストとして表現されます。つまり、
        %month = ('Jan',1,'Feb',2,'Mar',3);
        print($month{'Jan'},"\n");
    
    のように利用します。

    連想配列演算子
    keys()演算子は、現時点で連想配列に含まれている全キーを返します。
        %month = ('Jan',1,'Feb',2,'Mar',3);
        @list = keys(%month);
    
    では、@list は ('Jan','Feb','Mar')となります。 また、スカラーコンテキストではkeys()演算子は連想配列のキーの個数を表します。
    values()演算子は全ての値を全て返します。
        %month = ('Jan',1,'Feb',2,'Mar',3);
        @list = values(%month);
    
    では、@list は (1,2,3)となります。
    each()演算子は配列全体に対して繰り返しを行ないたい場合に有効である。
        %month = ('Jan',1,'Feb',2,'Mar',3); 
        @list=each(%month);
        print "@list\n"
        @list=each(%month);
        print "@list\n"
    出力
      % perl test.pl
      Mar 3
      Jan 1
    
  2. 制御構造

    if / unless 文

        IF (制御式) {
           ブロック
        } elsif {
           ブロック
        } else {
           ブロック
        }
    
    elsif, else ブロックは省略可能で、elsif はいくつあってもかまいません。 Perl では制御構造においてブレースは必ず必要です。 (Cのように複文で無い場合の省略はできません。) 制御式に関しては、真偽は制御式で与えられた文字列(数値の場合は文字列に変換される)が空文字列であるかまたは"0" の場合に偽となり、それ以外は真です。
        print("input number  1..13\n");
        $a=<STDIN>;
        chop($a);
        if ($a>7){
            print("Big\n");
        }else{
            print("Small\n");
        }
    実行
      % perl test.pl
      input number 1..13
      8
      Big
    
    ここで、<STDIN>は標準入力をコマンドラインで試した場合には、
      % perl -e 'print("input number 1..13\n");$a=<STDIN>; chop($a);if ($a>7){
       print("Big\n");}else{print("Small\n");}'  [Enter]
      input number 1..13
      4
      Small
      %
    
    のように確認できますね。

    if を unless に変えることにより「制御式を満たさなかったら」という記述が可能です。 unless 文もまたelse ブロックを持てます。

    while / until 文

        while (制御式) {
           ブロック
        }
    
    while 文は制御式を評価し、制御式の値が真ならブロックを実行し、制御式が偽になるまで繰り返します。 反対に「真でないかぎり実行せよ」は while を until に置き換えることにより表現できます。

    for 文

        for (初期条件; 制御式; 増加式) {
           ブロック
        }
    
    例) for 文を使ったHTMLにおける色を表示するCGI(簡易版)

    色を表示するCGI 色を表示するCGI(背景白) 色を表示するCGI(背景黒)

    foreach 文

    値のリストを受けとって、その値に対してブロックを実行する繰り返し構造として foreach 文があります。
        foreach $a (@list) {
           ブロック
        }
    
    @list の個々の要素に対して一つの要素を$a として、各1回の操作を実行します。(配列の要素の数だけ)
        @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
        foreach $day (@week) {
           print($day,"\n");
        }
    
    上は、想像どおりの結果になります。

宿題!

  1. Perl スクリプトの記述練習として、「鶴亀算」のプログラム。
  2. 前回の宿題について、連想配列を使いdateコマンドの結果を修正して 「本日は xx月xx日 xx曜日です。」という形式で表示する。また、カウンターを修正し、カウンターの値を各桁の数値の配列にして、配列の先頭から数値に対するカウンターファイルを表示するグラフィックカウンターを作る。(ヒント:数値を""を区切りに配列にとって、while や foreach を利用すればいいでしょう。)

    カウンターファイル

    これを、dgt0.gif などと名前をつけて保存して下さい。

[ 目次 / 前頁 / 次頁 ]
最終更新時刻
by Yoshiro Yamamoto