コンテキストのホームへ ホーム > Perlニュースレター > バックナンバー > 創刊号

ホーム

Perlニュースレター

Perl情報メモ

会社情報

トレーニングコース

!!速報!!
「プログラミングPerl第3版」が発売されました。 この機会にぜひお求めください。 詳しくは こちらをクリック
 
 

Perlニュースレター 創刊号 (2000年1月19日)

----------------------------------------------------------------------
        Perlニュースレター      創刊号 (2000年1月19日発行)

        http://www.context.co.jp/perlnews/      発行部数 1454部
----------------------------------------------------------------------

  ▼このメールはお申し込みいただいたアドレス(cond@context.co.jp)
    に無料でお届けしているものです。
  ▼以下のページで配送中止の手続きができます。
         http://www.context.co.jp/perlnews/
======================================================================
◆◆  目  次  ◆◆

  ◇ 初心者コーナー
        * 配列を操作する関数shift, unshift, push, pop
  ◇ 関数・モジュールWho's Who
        * 時刻を扱う関数
  ◇ 最新バージョン情報
  ◇ 編集後記
======================================================================
■■  初心者コーナー
======================================================================
        このコーナーでは、Perlを学び始めたばかりの人を対象に、基本とな
        るポイントを解説します。

        今回は配列を操作する関数を紹介します。
----------------------------------------------------------------------

配列の要素を参照するには、添え字(インデクス)を指定します。しかし、
Perlでは、添え字を指定して個々の要素をアクセスする以外に、配列そのもの
を直接に操作する関数が用意されています。このような関数をうまく活用すれ
ば、よりPerlらしいスクリプトを書くことができます。

Perlは、配列の先頭/末尾に対して要素を追加/削除するために、shift、
unshift、push、popという4つの関数を提供しています。これらの関数を表に
まとめると、次のようになります。

----------------+-----------------------+-------------------
                |  要素を追加(挿入)   |  要素を取り除く
----------------+-----------------------+-------------------
先頭に対して    |       unshift         |       shift
----------------+-----------------------+-------------------
末尾に対して    |       push            |       pop
----------------+-----------------------+-------------------

◇shift関数

shift関数は、引数として配列を1個受け取ります。そして、配列の先頭の要素
を取り除いて、それを返します。shift関数を実行するごとに、配列の長さ
(要素の個数)が1ずつ短くなり、残された要素はすべて1つずつ前にずれるこ
とになります。

shift関数の引数には配列を指定しなければなりません。リスト値を返すよう
な関数の戻り値などは指定できません。unshift、push、pop関数についても同
様な制限があります。

例えば、

        @a = (2, 4, 6, 8);
        $x = shift(@a);         # @aは (4, 6, 8) になる
        $y = shift(@a);         # @aは (6, 8) になる

というコードを実行すると、$xには2が、$yには4が代入され、@aの内容は(6,
8)となります。

shift関数の引数を省略すると、サブルーチンの中では@_が対象になります。
また、それ以外の場所では、@ARGVが対象となります。@_はサブルーチンへの
引数がセットされる特殊配列、@ARGVはスクリプトの起動時にコマンドライン
に指定した引数がセットされる特殊配列です。

◇unshift関数

第1引数で指定した配列の先頭に、第2引数以降の値を挿入します。挿入後の配
列の要素数を返します。もともと配列に入っていたすべての要素は、挿入した
要素の個数分だけ、後ろにずれることになります。

例えば、

        @a = (4, 5, 6);
        @b = (2, 3);
        $x = unshift(@a, @b);   # @aは (2, 3, 4, 5, 6) になる
        $y = unshift(@a, 0, 1); # @aは (0, 1, 2, 3, 4, 5, 6) になる

というコードを実行すると、@aの内容は(0, 1, 2, 3, 4, 5, 6)になり、$xに
は5、$yには7がセットされます。

◇push関数

第1引数で指定した配列の末尾に、第2引数以降の値を追加します。配列の長さ
は、追加した要素の個数だけ増えます。追加後の配列の要素数を返します。

例えば、

        @a = (1, 2, 3);
        @b = qw(four five);
        $x = push(@a, @b);      # @aは (1, 2, 3, 'four', 'five')になる
        $y = push(@a, 6);       # @aは (1, 2, 3, 'four', 'five', 6)になる

というコードを実行すると、@aは(1, 2, 3, 'four', 'five', 6)になり、$xに
は5、$yには6がセットされます。

◇pop関数

pop関数は、引数として配列を1個受け取ります。そして、配列の最後の要素を
取り除いて、それを返します。pop関数を実行するごとに、配列の長さ(要素
の個数)は1ずつ短くなります。

例えば、

        @a = (2, 4, 6, 8);
        $x = pop(@a);           # @aは (2, 4, 6) になる
        $y = pop(@a);           # @aは (2, 4) になる

というコードを実行すると、@aは(2, 4)になり、$xには8が、$yには6がセット
されます。

pop関数の引数を省略すると、サブルーチンの中では@_が対象になります。ま
た、それ以外の場所では、@ARGVが対象となります。@_はサブルーチンへの引
数がセットされる特殊配列、@ARGVはスクリプトの起動時にコマンドラインに
指定した引数がセットされる特殊配列です。

◇push関数とpop関数を使ってスタックを実現する

push関数とpop関数を使えば、配列をスタックとして扱うことができます。ス
タックを表す配列@stackを用意したとします。ここで、スタックに値$valueを
積むには、

        push(@stack, $value);

とします。スタックから値を取り出して変数$valueにセットするには、

        $value = pop(@stack);

とします。

配列@stackの要素の個数が、スタックに積まれているデータの個数になります。
scalar関数を使ってscalar(@stack)とすれば、配列@stackの要素数を得ること
ができます。(厳密な話をすれば、「配列をスカラーコンテキストで評価する
と、要素数が得られる」ということになります。このコンテキストというのは
重要な概念です。次回以降に改めて解説します。)

例えば、

        print "Stack has ", scalar(@stack), " element(s).\n";

とすれば、スタックに積まれているデータの個数(=配列@stackの要素数)を
表示できます。また、スタックが空(=データの個数が0)かどうかを調べるに
は、

        if (scalar(@stack) == 0) {
            die "Stack is empty!\n";
        }

などとします。このコードは、スタックが空ならば、die関数を呼び出してエ
ラーメッセージを表示して、スクリプトの実行を中止します。

======================================================================
■■  関数・モジュールWho's Who
======================================================================
        このコーナーでは、毎回、関数やモジュールをいくつか選んで、その
        使い方や落とし穴などを、実例を交えて紹介します。

        今回はtime、localtime、gmtime関数を取り上げます。
----------------------------------------------------------------------

今回のテーマは、時刻を扱う関数です。Perlでは時刻を、UNIXと同様な32ビッ
ト長整数(標準Cライブラリのtime_t型)で表現しています。この値は、1970
年1月1日午前0時UTC(この時刻をEpochといいます)からの秒数を表わしてい
ます。

◇time関数

現在の時刻を得るにはtime関数を使います。この関数は、呼び出されると、現
在の時刻を表わす整数値を返します。

        $now = time;

似たような名前でtimes関数というものがありますが、こちらはまったく働き
が違います。times関数は、プロセスが消費したCPU時間を返すものです。間違
えないように気を付けてください。

◇時刻を人間が見える形に変換する

32ビットで表現される時刻は、コンピュータにとっては扱いやすいものです。
例えば、2つの値の差を求めれば、その間に何秒が経過したかがわかります。
しかし、人間にとってはあまり理解しやすい代物ではありません。946652400
という数値を見て、「これは、日本標準時の2000年1月1日午前0時だ」とすぐ
にわかる人はあまりいないでしょう。

そこで、内部では32ビット整数を使い、人間が読むために表示する場合に限っ
て年月日時分秒に変換する、ということを行ないます。例えば、UNIXのファイ
ルのタイムスタンプは、ディスク上では32ビット整数で表現されています。そ
して、ls -lのようなコマンドを実行すると、人間が読みやすい形式に変換し
てから表示してくれるわけです。

◇gmtime、localtime関数

内部的な32ビットの整数で表現された時刻を、年月日時分秒に変換するための
関数がgmtimeとlocaltimeです。gmtimeはGMT(グリニッジ標準時)で表現した
値を返し、localtimeはローカル時間(日本ではJST)で表現した値を返します。
また、引数を省略すると現在の時刻(time関数が返す値)が使われます。

これらの関数をリストコンテキストで呼び出すと、次のような9要素のリスト
を返します。

        ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
                = localtime($t);
        ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
                = gmtime($t);

返される値は標準Cライブラリのstruct tm構造体の内容に(ほぼ)そのまま対
応しています。値はいずれも数値で、その意味は次の通りです。(詳しくは、
UNIXのlocaltime(3)マニュアルページをご覧ください。)

        $sec    秒(0〜59)
        $min    分(0〜59)
        $hour   時(0〜23)
        $mday   日(1〜31)
        $mon    月(0〜11: 0が1月)
        $year   年(西暦から1900を引いた値)
        $wday   曜日(0〜6: 0が日曜日)
        $yday   年の始めから数えて何日目か(0〜365: 0が1月1日を表す)
        $isdst  サマータイム期間中なら1、そうでなければ0

このうち、$mon、$year、$wdayの3つの値には注意が必要です。

$mon(月)と$wday(曜日)の値は、それぞれ0から始まるようになっています。
つまり、$monが0なら1月、$wdayが0なら日曜日を表わすのです。これは、月や
曜日を「名前」に変換するために、配列の添え字として使うことを考えている
のです。つまり、

        # 曜日の変換用の配列
        @wday_table = qw(Sun Mon Tue Wed Thu Fri Sat);

        # 月の変換用の配列
        @mon_table  = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);

という配列を用意しておけば、$wday_table[$wday]、$mon_table[$mon]によっ
て、それぞれ曜日、月を表す文字列が得られるわけです。

もちろんこれは英語の場合の話で、日本語では事情が変わります。日本では、
曜日は名前で表わしますが、月は数字で表わします。ですから

        print $mon, "月", $mday, "日\n";        # 誤り!!

としてしまうと、1か月前の日付けを表示してしまいます。正しくは、$monに1
を加えて

        print $mon + 1, "月", $mday, "日\n";    # 大丈夫

としなければなりません。これはよく間違えるので注意しましょう。

$year(年)には、西暦から1900を引いた値がセットされます。つまり、1999
年なら99、2000年なら100という値になります。この値が意外に曲者で、いわ
ゆる2000年問題の原因となります。

例えば、次のように、西暦の下2ケタを表示するのに、$yearの値をそのまま表
示しているスクリプトがあったとします。

        # 年の下2ケタを表示: 誤り!
        printf("%02d/%02d/%02d\n", $year, $mon + 1, $mday);

このスクリプトは、1999年までは「99/12/31」などと表示しますが、2000
年になると、「100/01/01」と表示してしまいます!

正しくは、次のように$yearに1900を加えた上で、100で割って余りを取らなけ
ればなりません。

        # 年の下2ケタを表示: Y2K compliant
        printf("%02d/%02d/%02d\n", ($year + 1900) % 100, $mon + 1, $mday);
        # $yearを100で割った余りでもOK
        printf("%02d/%02d/%02d\n", $year % 100, $mon + 1, $mday);

また、4ケタの西暦を表示するのに、$yearの前に"19"という文字列をくっつけ
て次のようにしているスクリプトもあります。

        # 年を4ケタで表示: 誤り!
        print "19", $year, "年", $mon + 1, "月", $mday, "日\n";

このスクリプトは、2000年になると、「19100年1月1日」と表示してしまいま
す。年を4ケタで表示するには、次のように$yearに1900を加算してやらなけれ
ばなりません。

        # 年を4ケタで表示: Y2K compliant
        print $year + 1900, "年", $mon + 1, "月", $mday, "日\n";

昨年(1999年)中にこのような話をすれば実にタイムリーだったのですが、今
となっては「おそかりし由良之助」であります。

localtime関数やgmtime関数をスカラーコンテキストで評価すると、ちょうど
UNIXのctime(3)のような文字列が返されます。例えば、

        $str = localtime;

とすると、現在の時刻を次のような形式で表示した文字列が変数$strに得られ
ます。

        Tue Jan 18 11:21:05 2000

また、POSIXモジュールで定義されているPOSIX::strftime関数を使えば、さら
に細かく書式を指定することができます。

◇timelocal、timegm関数

localtimeやgmtime関数の逆方向の変換を行なうには、標準モジュール
Time::Localで定義されているtimelocal、timegm関数を使います。

これらの関数を使うには、まずスクリプトの先頭で

        use Time::Local;

として、Time::Localモジュールを使用することを宣言しておきます。これら
の関数は次のようにして呼び出します。

        $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
        $time = timegm($sec,$min,$hour,$mday,$mon,$year);

これらはいずれも、32ビット整数で表現した時刻を返します。引数は、先ほど
説明したlocaltime、gmtimeの戻り値と共通です。$monには0〜11の値を指定し、
$yearには西暦から1900を引いた値を指定することに注意してください。

======================================================================
■■  最新バージョン情報                        2000年1月18日現在
======================================================================
        このコーナーでは、Perl処理系とユーティリティの最新バージョンと
        その入手場所を紹介します。
----------------------------------------------------------------------
●perl●

  現在、perlは安定版(stable version)と開発版(development version)
  の2つのブランチに枝分かれして開発が行なわれています。

  安定版(stable version)は安定した動作を最大の目的としているバージョ
  ンです。原則として新たな機能の追加は行なわずに、バグの修正のみが行な
  われます。特に理由のない限り、安定版を使用するのがよいでしょう。

  開発版(development version)は、次期バージョンのベースとなるもので、
  どんどん新しい機能が追加されます。実験的(experimental)なバージョン
  とされており、動作の安定性は期待できません。

  ◇perl安定版(stable version)
        最新バージョンは5.005_03です。

          ▼perl 5.005_03の入手先
            http://www.perl.com/CPAN/src/stable.tar.gz

  ◇perl開発版(development version)
        最新バージョンは5.005_63です。

          ▼perl 5.005_63の入手先
            http://www.perl.com/CPAN/src/devel.tar.gz

●jperl●

  jperlは、perlを日本語対応にするためのパッチです。最新バージョンは
  jperl5.005_03-990822.pat.gzです。

    ▼jperl5.005_03-990822.pat.gzの入手先
      http://www.perl.com/CPAN/authors/Hirofumi_Watanabe/jperl5.005_03-990822.pat.gz

●Windows版●

  ◇ActivePerl
        ActivePerlは、ActiveStateによるWin32(Windows 95/98/NT)用の
        perlです。フリーで入手できます。最新バージョンはBuild 522で、
        5.005_03をベースにしています。バイナリ(とソース)が配布されて
        います。

          ▼ActivePerl Build 522の入手先
            http://www.activestate.com/ActivePerl/download.htm

          ▼ActiveState
            http://www.activestate.com/

  ◇ActivePerl(日本語版)
        ActivePerlにjperlパッチを組み込んで日本語対応にしたものです。
        最新バージョンはjperl522で、ActivePerl Build 522と
        jperl5.005_03-990822.pat.gzをベースにしています。バイナリ(と
        ソース)が配布されています。

          ▼jperl522の入手先
            http://www.shonan.ne.jp/~kipp/perl/jperl_win32.html

●Macintosh版●

  ◇MacPerl
        Macintosh用のperlです。最新バージョンはMacPerl 5.20r4で、
        5.004_04をベースにしています。バイナリが配布されています。

          ▼MacPerl 5.20r4の入手先
            http://www.perl.com/CPAN/ports/mac/Mac_Perl_520r4_appl.bin

          ▼MacPerlに関する情報
            http://www.perl.com/CPAN/ports/index.html#mac

  ◇MacJPerl(日本語版)
        Macintosh用の日本語対応のperlです。最新バージョンはMacJPerl
        5.2.0r4 J1です。MacPerl 5.20r4(5.004_04ベース)と
        jper5.004_04-980303.patをベースにしています。バイナリが配布さ
        れています。

          ▼MacJPerl 5.2.0r4 J1の入手先
            http://world.std.com/~habilis/macjperl/MacJP5.j.htm

●日本語のコード変換ユーティリティ●

  ◇jcode.pl
        日本語のコード変換を行うためのライブラリです(Perl 4でもPerl 5でも
        使えます)。最新バージョンは2.11です。

          ▼jcode.pl 2.11の入手先
            ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/jcode.pl-2.11

          ▼jcode.plの変更履歴
            ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/jcode.pl-history

          ▼jcode.pl の私的な解説書
            http://ina.kappe.co.jp/~sabre/kcode/jcode.html

  ◇Jcode.pm

        日本語のコード変換を行うためのモジュールです(Perl 5専用。Perl
        4では使えません)。最新バージョンは0.60です。

          ▼Jcode.pmの入手先
            http://openlab.ring.gr.jp/Jcode/index-j.html

●その他●

  Perlニュースレターの発行者(近藤 嘉雪)による、Perlに関する情報をま
  とめたページです。

    ▼Perl情報メモ
      http://www.context.co.jp/~cond/perlinfo/

======================================================================
■■  編集後記
----------------------------------------------------------------------
▼1999年12月22日にアナウンスして、準備を始めた「Perlニュースレター」で
  すが、当初の予想以上の多くのお申し込みをいただきました。大変ありがと
  うございます。うれしい反面、ちょっとビビっております:-)
▼1月19日に創刊号を発行することができました。予告した1月中旬に何とか間
  に合って、ホッと一息ついているところです。
▼今回は、「初心者コーナー」と「関数・モジュールWho's Who」は、どちら
  も関数の紹介になってしまいました。「初心者コーナー」は、関数だけでは
  なく、初心者の人にとって役に立つさまざまなトピックを取り上げる予定で
  す。今後にご期待ください。
▼第2号は、2月の初旬に発行の予定です。
                                近藤 嘉雪 (cond@context.co.jp)
======================================================================
Perlニュースレター 創刊号 (2000年1月19日発行)

        主筆:-) 近藤 嘉雪
        発行元  有限会社コンテキスト(http://www.context.co.jp/)

▼バックナンバーは:     http://www.context.co.jp/perlnews/bn/
▼配信申込/配信中止は:  http://www.context.co.jp/perlnews/
▼ご意見・ご感想・お問い合わせは:
                        mailto:perlnews@context.co.jp
======================================================================
Copyright 2000  (有)コンテキスト, All rights reserved.
「Perlニュースレター」に掲載された記事を許可なく転載することを禁じます。
======================================================================
ご質問・お問い合わせはperlnews@context.co.jpまで
Copyright (C) 2001 Context, Inc. All rights reserved.