Perlノート講座

はじめてのPerlプログラミング!

HTML/ CSS/ CGI-Perl/ JavaScript/ JavaApplet/ AccessUp/ Internet/ EnglishLearn/ ちゃいちゃん天使/ 天使メッセージ/ 飯田ワールド/ 結城ワールド/ プロフィール/ WEB相談室/ WEBアンテナ/ WEBリーダー/ 燈明日記/ 法華経ブログ/ yahoo

◆ はじめに

ごく普通の言語(COBOL,C,Java,VB等)を知っている人が、Perlをやり始めるといろいろと悩むことがあります。

それは、以下の感じです。

本ページは、上記ようなハードルを一つ一つクリアにしていけたらと思います。

また、全く初めてのPerlプログラミングの人にも、無理なく理解ができるように心がけました。

分かってくると、Perlほど面白く、ラクチンな言語は、たぶんありません。

なので、この際にマスターしてしまいましょう!

尚、ご感想、ご意見、誤字、脱字、間違い等がありましたら遠慮なくPerlノート掲示板へご指摘ください。

◆ サイト最新情報

◆ インデックス

◆ コンテンツ

【その0】プログラミングの基礎の基礎

◆ はじめに

今ここを読んでいるということは、プログラミングに興味があり、Perlでもやってみようかなぁ・・・なんて思っているのだと思います。

そのプログラミングは、基礎を知らないで突っ走っても、なかなか上達しないですね。

なので、とりあえず本コンテンツ『Perlノート講座』をひと通り読んでいただければ、プログラミングとPerlの基礎がマスター出来るようになっているのです(たぶん)。


そもそも、プログラミングは、かなり昔、メモリ上に直接命令コードを書いて、それをCPUに読み込ませて、計算したり、プリンタ出力したり・・・、していた時代がありました。

メモリ上に直接命令コードを書くのは、凄く大変なことでした。

そこで徐々に、機械語ができ、アセンブラができ、フォートランやコボルやC言語ができて、今の時代になってPerlやJavaなどが主流になってきたのです。


特にPerlは、私が知る限り、プログラミングが非常にラクチンに出来る言語なのです。

なので、この際、Perlをマスターしてしまいましょう!


まずは基礎の基礎からで、プログラムの6つの基本要素を理解し、そして以下の拡張要素や補助要素をからめて徐々に完成度のあるプログラミングをマスターして参りましょう!

では、スタートです!


◆ プログラムの基本要素

プログラムの基本要素は、以下の6つです(たぶん)。

プログラムを組むときは、この6つの要素を組み合わせます。


・変数

変数は以下の3種類があります。


・演算子

以下以外にもまだまだ沢山あります。


・代入文

代入文は、代入演算子を使って、以下のように変数へ値を代入します。

my $value = 10;

・判断文

判断文は、if文等で、以下のような感じで使用します。

if ($value == 10) {
    $value += 1;
}
else {
    $value += 2;
}

・繰り返し文

繰り返し文は、for文やforeach文等で、以下のような感じで使用します。

my @value;
for (my $i = 0; $i < 10; $i++) {
    $value[$i] = $i * 2;
}

・リテラル

リテラルとは、プログラムのソースコード中に使用される数値や文字列のことです。

 
◆ プログラムの拡張要素

プログラムは、基本要素の組み合わせで、大体できてしまいます。

しかし、実際は、上記5つの基本要素以外に、以下の拡張要素も組み合わせます。


◆ プログラムの補助要素

プログラムは未来の自分も含めて、誰にでも分かりやすい、プログラム作りを心がけないとなりません。

そのために以下を熟慮します。


◆ プログラミングのはじめの一歩

最後にPerlでのプログラミングのはじめの一歩『Hello World』です。

本当は『print "Hello World";』だけなんですが、上記の要素を入れてみました。

use strict;
use warnings;

my $strmsg = 'Hello World';
if ($strmsg eq 'Hello World') {
    for (my $i = 0; $i < length($strmsg); $i++) {
         print substr($strmsg, $i, 1);
    }
}

【その1】変数等の頭文字って何を意味するの?

他言語、特にオーソドックスなcobol,c,java,vb等の人がPerlをやり始めると謎だらけで悩むことになりますね。

そんな人のために、僭越ながら私が謎を解き明かしていきますよ! Perlerの方は温かく見守ってくださいね(^o^)


◆変数等の頭文字って何を意味するの?

Perlをやり始めると変数等の頭文字($,@,%,&,*,何も無し)が気になります。


『$』が付くシンボルは、スカラー変数で、数値や文字列など何でも入る・・・VBで言えば、variant型のような変数です。

『$』はScalarの『S』に似ているので、スカラー変数を表します。


『@』が付くシンボルは、配列変数で、配列の要素はスカラー変数と同じで、何でも入る。

『@』はarrayの『a』に似ているので、配列変数を表します。


『%』が付くシンボルは、ハッシュ変数で、ハッシュはkeyとvalueを対で持っていて、valueはスカラー変数と同じで、何でも入る。

『%』はkeyとvalueの対を表していて、ハッシュ変数を表します。


『&』が付くシンボルは、サブルーチンで、実は『&』を頭に付けるより、尾に『()』をつけてサブルーチンを明示する方が多いです。

『&』はSubの『S』に似ているので、サブルーチン(これは自信がない)を表します。

(モダンPerlでは、『&』は付けないとのことです。右を参照のこと『第124回 サブルーチンの頭に&は普通つけない』)

『*』が付くシンボルは、型グロブで、頭文字以外同名のシンボルすべてを表します。

『*』と言えば、ワイルドカードですね。


何もつかないシンボルは、ベアワードで、ファイルハンドル、引数のない組み込み関数、ヒアドキュメントの終端値、ラベル、単なる文字列などなど・・・。


◆ファニー文字

ちなみに、これらの頭文字のことをPerl では「ファニー文字(funny character)」とよんでいます。

実はファニー文字を使うことにより、将来使われるであろう予約語やキーワードとかぶることがありません。

他の言語では、かぶる可能性があり、かぶった時に過去の資産が使えなくなるのです。

つまり、Perlでは、ファニー文字を使うことにより、過去の資産が使えなくなることが無いのです。


◆サンプル
$hoge = 123;                      # スカラー変数
@hoge = (1, 2, 3);                # 配列変数
%hoge = (a => 1, b => 2, c => 3); # ハッシュ変数

print "-----&hoge------------\n";              
&hoge;                            # サブルーチン
print "-----&foox(*hoge)------\n";              
&foox(*hoge);

sub hoge {
   print "$hoge", "\n";                   # スカラー変数
   print "$hoge[0]$hoge[1]$hoge[2]", "\n";# 配列変数
   print "$hoge{a}$hoge{b}$hoge{c}", "\n";# ハッシュ変数
}                                         
sub foox {
   (*foo) = @_;
   print "$foo", "\n";                 # スカラー変数
   print "$foo[0]$foo[1]$foo[2]", "\n";# 配列変数
   print "$foo{a}$foo{b}$foo{c}", "\n";# ハッシュ変数
   print "-----&foo--------------\n";              
   &foo;                               # サブルーチン
}

◆実行結果
C:\perltest>perl sysbol.pl
-----&hoge------------
123
123
123
-----&foo(*hoge)------
123
123
123
-----&foo--------------
123
123
123

上記サンプルは、型グロブと各変数の関係を示すため、すべてグローバル変数になっています。

しかし、モダンPerlではなるべくグローバル変数は使わず、myでローカル変数にして処理するのが推奨です。

また、サブルーチンの『&foo;』も『foo();』の記述の方が推奨です。

【その2】特殊変数 $_ とは

まず、以下のソースを見てください。

use strict;
use warnings;

while (<DATA>) {
    if (/^h.*e$/) {
        print;   # hogeを表示する
    }
}
__END__
hoge
foo

Perl初心者や他言語から来た人が・・・実はかつての自分が、このソースを見た時に???のオンパレードでした。

これを以下のようにすると・・・。

use strict;
use warnings;

while ($_ = <DATA>) {
    if ($_ =~ /^h.*e$/) {
        print $_;   # hogeを表示する
    }
}
__END__
hoge
foo

かなり分かりやすくなりますね。

このように、Perlでは、デフォルトで『$_』という特殊変数を用いるようになっているのです。

そして、『$_』は省略できるのです。

そして、ちょっとベテランになると、省略の方が良くなるのです。


ちなみに、ソースを簡単に解説しときます。

補足

$_は、普通はブロック内でローカル化されのですが、例外的にwhile文ではローカル化されません。

なので、while文での$_の使用は、注意が必要です。

$_ = 100;
print $_, "\n";
while (<DATA>) {
    print $_;
}
print $_, "\n"; # 100の値でなくなる
__END__
aaa
bbb
ccc

【その3】コンテキストで意味が変わる関数

今回は、他言語経験者にとって、Perlでの最大の謎『コンテキスト』です。


まず、Perlでは、スカラー変数と配列変数とハッシュ変数があります。


スカラー変数には、文字列や数値、リファレンス等のスカラー値を代入します。

配列変数やハッシュ変数には、リスト値を一気に代入します。


Perlでは、スカラー変数にスカラー値を代入することをスカラーコンテキストといいます。

また、配列変数とハッシュ変数にリスト値を一気に代入することをリストコンテキストといいます。


つぎに、関数は、引数を入力*1として結果をリターン値として返します。

このリターン値が、代入先の変数のスカラー変数か配列変数またはハッシュ変数かによって、スカラー値を返したり、リスト値を返したりするのです。


つまり、コンテキストによって同じ関数でもリターン値が変わるのです。

まぁ、すべての関数がそうなるわけではないのですが、リスト値を処理する関数は大体そうなります。


◆サンプル(localtime.pl)
use strict;
use warnings;

my $localtime = localtime(time); # スカラーコンテキスト
print "$localtime \n";
my @localtime = localtime(time); # リストコンテキスト
print "@localtime \n";

#以下もリストコンテキスト
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); 
local ($, , $\) = (' ', "\n");
print($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst); 

◆サンプル実行結果
C:\perltest>perl localtime.pl
Sun Jun 28 07:31:27 2009
27 31 7 28 5 109 0 178 0
27 31 7 28 5 109 0 178 0

◆補足1

実は、関数だけでなく、以下のような単純な代入でもコンテキストがあります。

use strict;
use warnings;

my $localtime = localtime(time); # スカラーコンテキスト
my @localtime = localtime(time); # リストコンテキスト

my $x = @localtime;        # スカラーコンテキスト
print $x, "\n";            # 配列の要素数(9)が表示

my @x = $localtime;        # リストコンテキスト
print @x, "\n";            # スペースをデリミタにしたリストで取り込み、配列にて表示(Sun Jun 28 07:42:39 2009)

◆補足2

コンテキストでリターン値が変わる主な関数達

こうやって見ると、リストコンテキストではリスト値を返す便利な関数が、スカラーコンテキストでは、その要素数を返すケースが多いようです。


◆補足3

上記は、スカラーコンテキストとリストコンテキストの2つでしたが、実は、まだ違う種類のコンテキストがあります。

大きく分けて、スカラーコンテキストとリストコンテキストとボイドコンテキストの3つあり、さらにスカラーコンテキストにはブール値、文字列、数値、不定の4つがあります。

*1:もちろん、出力のときもある

【その4】構造体がないデータ構造

普通の言語、たとえば、C言語とかVB等では、データ構造を定義できる構造体があります。

もっと昔だと、構造体がなく、すべて配列で処理する言語もありました(昔のコボルとかベーシック)。


で、perlのデータ構造なのですが、ご存知の通り、スカラー、配列、ハッシュの3種類しかありません。

そう、構造体がないのです。


では、他言語で構造体処理のクセを身に付けてしまった人は、どうすればよいのでしょうか・・・。

実は、構造体は、ハッシュで表現ができるのです。

構造体の配列も、同じく、ハッシュの配列で表現ができるのです。


以下にC言語の構造体とPerlのハッシュ、そして、構造体配列とハッシュの配列のサンプルを書いてみました。

たしかに、C言語の構造体は、Perlのハッシュで表現ができていますね!


◆サンプル:C言語の構造体
struct db_login {
    char svnm[7];
    char svnm2[9];
    char loginid[31];
    char password[31];
    char db_string[45];
}; 
struct db_login shisha={"svr00X", "X支社", "id", "passwd", "svr00Xs"];

printf("hostname=%s\n",  &shisha.svnm[0]);
printf("hostname2=%s\n", &shisha.svnm2[0]);
printf("loginid=%s\n",   &shisha.loginid[0]);
printf("password=%s\n",  &shisha.password[0]);
printf("db_string=%s\n", &shisha.db_string[0]);

◆サンプル:Perlのハッシュ
my %shisha = (
    svnm      => 'svr00X',
    svnm2     => 'X支社',
    loginid   => 'id',
    password  => 'passwd',
    db_string => 'svr00Xs'
);

printf("hostname=%s\n",  $shisha{svnm});
printf("hostname2=%s\n", $shisha{svnm2});
printf("loginid=%s\n",   $shisha{loginid});
printf("password=%s\n",  $shisha{password});
printf("db_string=%s\n", $shisha{db_string});

◆サンプル:C言語の構造体配列
#define SHISHA_CNT 3
struct db_login {
    char svnm[7];
    char svnm2[9];
    char loginid[31];
    char password[31];
    char db_string[45];
}; 
struct db_login shishas[SHISHA_CNT]={
        "svr001", "A支社", "id", "passwd", "svr001s",
        "svr002", "B支社", "id", "passwd", "svr002s",
        "svr003", "C支社", "id", "passwd", "svr003s",
};
int i;
for (i =0; i < SHISHA_CNT; i++) {
    printf("hostname=%s\n",  &shisha[i].svnm[0]);
    printf("hostname2=%s\n", &shisha[i].svnm2[0]);
    printf("loginid=%s\n",   &shisha[i].loginid[0]);
    printf("password=%s\n",  &shisha[i].password[0]);
    printf("db_string=%s\n", &shisha[i].db_string[0]);
}

◆Perlのハッシュの配列
my @shisha = ({
                svnm      => 'svr001',
                svnm2     => 'A支社',
                loginid   => 'id',
                password  => 'passwd',
                db_string => 'svr001s'
              },
              {
                svnm      => 'svr002',
                svnm2     => 'B支社',
                loginid   => 'id',
                password  => 'passwd',
                db_string => 'svr002s'
              },
              {
                svnm      => 'svr003',
                svnm3     => 'C支社',
                loginid   => 'id',
                password  => 'passwd',
                db_string => 'svr003s'
              },

);

for (my $i = 0; $i < @shisha; $i++) {
    printf("hostname=%s\n",  $shisha[$i]{svnm});
    printf("hostname2=%s\n", $shisha[$i]{svnm2});
    printf("loginid=%s\n",   $shisha[$i]{loginid});
    printf("password=%s\n",  $shisha[$i]{password});
    printf("db_string=%s\n", $shisha[$i]{db_string});
}

Perlでは、リファレンスと無名配列と無名ハッシュが理解できると、データ構造は自由自在なのです!

たとえば

◆関連リンク

【その5】foreach文がfor文に

結論から言うと、Perlでは、for文とforeach文は同じ物なのです。

というか、for文のforは、foreachの省略形とのことです(ホントかな)。

と同じとはいいながら、for文とforeach文ではイメージが違います。


◆for文の基本
for (my $i = 1; $i < 10; $i++) {
    処理
}

◆foreach文の基本
foreach my $scalar (@array) {
    処理
}

◆for文とforeach文の可換

冒頭で述べたように、for文とforeach文は同じで可換なのです。

foreach (my $i = 1; $i < 10; $i++) {
    処理
}
for my $scalar (@array) {
    処理
}

で結論は、イメージを重んじる人はイメージ通りに、簡素にしたい人はfor文オンリーに、たぶん、foreach文オンリーは無しでしょう・・・たぶん。

【その6】Perlでの文字列

VB系とかDOSコマンド系での文字列はダブルクォーテーションです。

また、SQL系での文字列は、シングルクォーテーションです。


Perlでの文字列は、上記両方です。

違いは、ダブルクォーテーションでは変数が展開され、シングルクォーテーションでは展開されません。

また、qクォート演算子とqqクォート演算子も同じ関係で文字列を表します。

my $strdata1 = '文字列1';
my $strdata2 = "文字列2 $strdata1";
my $strdata3 = q{文字列3};
my $strdata4 = qq{文字列4 $strdata3};
print $strdata1, "\n";  # 文字列1
print $strdata2, "\n";  # 文字列2 文字列1
print $strdata3, "\n";  # 文字列3
print $strdata4, "\n";  # 文字列4 文字列3

あと、qwクォート演算子を使うと文字列のリストの入力が楽になりますね。

my @strlist1 = ('文字列1',  '文字列2', '文字列3');
my @strlist2 = qw{文字列1 文字列2 文字列3};         # 上と等価(ただし、スペースが文字列中にあるときはNG)
print "@strlist1", "\n"; # 文字列1 文字列2 文字列3 
print "@strlist2", "\n"; # 文字列1 文字列2 文字列3

◆補足1:ダブルクォート文字列での特殊文字のエスケープ

たとえば、ダブルクォート文字列にダブルクォートを記述する場合は、その前に \ を置いてエスケープします。

尚、シングルクォート文字列の中でのシングルクォート( ' )のエスケープは( \' )とします。


◆補足2:ダブルクォート文字列で展開される \ による文字エスケープ

以下は、ダブルクォート文字列の中で各々の意味(制御コード)に展開されます。

【その7】サブルーチンの呼び出し方

◆ イントロ

まず、Perlでのサブルーチンは関数と等価です。

そして、関数の呼び出し方には、『&』のファニー文字を付けたり、付けなかったり・・・。

また、関数名の後に『()』小カッコを付けたり、付けなかったり・・・。

またまた、『&』も『()』も付けなく、ベアワードになったりと・・・。


これらは、『組み込み関数やインポートしたモジュール関数』と『ユーザ定義関数』で意味が違ってきます。

なので、各々について対比して解説をしてみました。


尚、以下は、あくまでも私のコーディング方針で、強制的なものではありません。


◆ 『&』ファニー文字について

組み込み関数やインポートしたモジュール関数は、『&』ファニー文字は付けない。

組み込み関数等に『&』を付けるとエラーになる。(ユーザ定義関数を探しに行ってエラーとなる)


ユーザが定義できる関数(サブルーチン)は、いろいろな理由で『&』を付けず、ユーザ定義関数は関数名の後に『()』小カッコを付ける方がよい。

しかし、万が一、組み込み関数とユーザ定義関数が同名になった時は、『&』でユーザ定義関数を呼び出すことができます。

use strict;
use warnings;

my $hoge1 = time;   # 組み込み関数
my $hoge2 = &time;  # ユーザ定義関数

print $hoge1 , "\n";
print $hoge2 , "\n";

sub time {
    return 'hoge';
}

◆ 関数名の後の『()』小カッコについて

組み込み関数やインポートしたモジュール関数は、『()』小カッコを付けない方がよい。

カッコを付けてもOKですが、ユーザ定義関数以外であることを明示するために『()』を付けない方がよい。


ユーザが定義できる関数(サブルーチン)は、『()』小カッコを付ける。

関数をロジックの前置きに定義すると、カッコなしでもOKですが、そうしない。『()』小カッコを付けてユーザ定義関数を明示する。

use strict;
use warnings;

my $hoge1 = localtime time;    # 組み込み関数
my $hoge2 = &localtime(time);  # ユーザ定義関数

print $hoge1 , "\n";
print $hoge2 , "\n";

sub localtime {
    return $_[0];
}

◆ 引数のない関数について

引数のない場合の組み込み関数やインポートしたモジュール関数は、ベアワードにする。

引数のない場合のユーザが定義できる関数(サブルーチン)は、『()』を付ける方がよい。


◆ ユーザ定義関数は、『&』をつけない?

『&』は、基本的につけません。これに関しては以下のリンク先を参照願います。

また、id:miyagawa氏から、以下のようなコメントも頂きました。

将来組み込み関数が増えた場合でも、それらの関数は use feature しないと有効にならない仕組みになっている(5.10のsay や givenなど) ので、何もなしに動かなくなる、ということはないはず。


◆ 結論

【その8】サブルーチンのデフォルトのリターン値

Perlでのサブルーチンは、実は関数とイコールです。


そもそも、サブルーチンと関数の違いは、リターン値を返すか返さないかの違いです。

しかし、Perlでは、サブルーチンでもリターン値を返すことができるので、事実上、関数とイコールなのです。


Perlのサブルーチンはsubキーワードから書き始めます。

リターン値はreturnキーワードで記述します。


しかし、returnキーワードをあまり見かけないのです。

またしかし、それでもリターン値が返って来ているみたいなのです。


そう、実は、returnキーワードは省略可能なのです。

Perlでは、サブルーチンの最後に評価した式の値が、returnキーワードがあってもなくても、リターン値になるのです。


use strict;
use warnings;

sub closure {
    my $value = shift;
    sub { $value++ };   # return sub { $value++ }; と等価
}

Perlをやり始めると、subだし、returnキーワードはないケースが多いし、本当にリターン値が返っているのだろうか・・・。

なんて、悩む時期があるのです。


とにかく、サブルーチンの最後に評価した式の値が、returnキーワードがあってもなくても、リターン値になるのです!

【その9】単独shiftとは何か?

Perlでのshift関数は、普通、配列変数を引数にとり、配列変数から一番若いインデクスの要素を取り出します。

しかし、配列変数の引数がない単独shiftを結構見かけます。


これは、mainモジュールでは「@ARGV」がデフォルトの引数で、sub内では、「@_」がデフォルトの引数になるのです。

ちなみに、「@ARGV」は、コマンドラインの引数の配列で、「@_」は、サブルーチンの引数の配列です。


◆サンプル
use strict;
use warnings;

my $arg = shift || 2000;
print $arg, "\n";

subx();
subx(4000);

sub subx {
    my $para = shift || 3000;
    print $para, "\n";
}

◆サンプル実行結果
C:\perltest>perl shift.pl 1000
1000
3000
4000

C:\perltest>perl shift.pl
2000
3000
4000

【その10】マッチ演算子の区切り文字

マッチ演算子はスカラー変数に格納されている文字列を正規表現を使ってマッチするか判断する演算子です。

通常、区切り文字『/』を使って以下のようになります。

if ($_ =~ m/abc/) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}

しかし、以下のようにも書けるのです。

if (m@abc@) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}

そう区切り文字は、『/』でなくとも、任意の非英数字(空白文字は除く)でも大丈夫なのです。

またしかし、非英数字でもカッコ系は、開き/閉じのペアでないとなりません。

またまたしかし、以下の3つに関しては、注意が必要です。

  1. 『#』を使う場合は、マッチ演算子との間にスペースを入れないこと(入れるとコメント認識される)。
  2. 『'』を使う場合は、パターン内で変数が展開されなくなる。
  3. 『?』を使う場合は、??演算子になる(1回しかマッチしない)

ただし、区切り文字『/』は、他の非英数字と違い、mを省略できます。

if (/abc/) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}

◆サンプル(m.pl)
use strict;
use warnings;

my $s = "abcxxxxabcyyyyabczzzz";
if ($s =~ m/abc/) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}
if ($s =~ m@abc@) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}
if ($s =~ m<abc>) {
   print "マッチした! \n"; 
}
else {
   print "マッチしない!\n"; 
}

my $a = 0;
while($s =~ m/abc/g) {
   $a++;
}
print $a, "\n";

$a = 0;
while($s =~ m?abc?) {
   $a++;
}
print $a, "\n";

◆実行結果
C:\perltest>perl m.pl
マッチした!
マッチした!
マッチした!
3
1

【その11】正規表現

今回の謎は、正規表現です。

はじめての人のために解説をしてみました。


他言語からの人は、正規表現を使う機会がなかったかもしれませんが・・・。

Perlでは、正規表現を使うための言語と言っても過言ではありません。

正規表現を使うことによりテキスト(文字列)編集処理が飛躍的に楽になるのです。


そもそも正規表現は、人体の神経回路網を数学的に説明するための方法として開発されました。その後、UNIXのケン・トンプソンによってコンピュータでの検索アルゴリズムに引き継がれました。ちなみに、正規表現を初めて使用したアプリケーションは、UNIX のエディタedやexの祖となったQEDというエディタのようです。QED、ed、grep等を経てPerlに引き継がれたようです。 (そもそもの正規表現は、参考リンクのリンク先を参照しました)


では、まずはじめにテストデータ、family.txt を用意します。

このテストデータを元にしてサンプルプログラムを踏まえて解説をしていきますね。


・family.txtファイルの内容
macha koike
yachu koike
chaichan koike
hiro koike
mama koike
papa koike
koike 6
ni-bo- horie yasashii
nee-nee horie chottokowai
60 horie
ma-kun murai
sachi murai
kazumasa murai
hisa

◆マッチング

まず始めに、苗字が『koike』の人をマッチさせてみましょう。(サンプル01 sample01.pl)

while($_ = <STDIN>){
   if($_ =~ /koike/){
      print $_;
   }
}

上記は、標準入力からデータを読み込んで一行づつループし、その行データに『koike』がマッチするか調べ、マッチした時に行データを標準出力しています。

『$_ =~ /koike/』の式はマッチした時は、真を返し、マッチしない時は、偽を返します。

では、実行してみましよう。

% sample01.pl < family.txt
macha koike
yachu koike
chaichan koike
hiro koike
mama koike
papa koike
koike 6
・補足1

逆にマッチしない時は真を返し、マッチした時は偽を返すには『$_ !~ /koike/』とします。


◆アンカー

まずいことに、名前以外の koike 6 もマッチてしまいました。

そこで、koikeという文字列がデータの末尾に一致する場合のみに限定します。(サンプル02 sample02.pl)

while($_ = <STDIN>){
   if($_ =~ /koike$/){
      print $_;
   }
}

/koike$/の『$』は、文字列の末尾にマッチする記号で、アンカーと言います。

アンカーには、他に文字列の先頭にマッチする『^』と単語の境界(正確には、単語の先頭あるいは末尾)にマッチする『\b』、それ以外の部分にマッチする『\B』があります。

では、実行してみましよう。

% sample02.pl < family.txt
macha koike
yachu koike
chaichan koike
hiro koike
mama koike
papa koike

今度は上手く行きました。


・アンカー『^』の検索(サンプル03 sample03.pl)

つぎに、アンカー『^』を使って『k』で始まる人を検索してみましょう

while(<STDIN>){
   if(/^k/){
      print;
   }
}

尚、『$_』は省略可能です。

% sample03.pl < family.txt
koike 6
kazumasa murai

・補足2

また、アンカーには、 文字列の先頭にマッチする 『\A』 と文字列の末尾にマッチする 『\Z』 があります。

『\A』 と 『^』 、『\Z』 と 『$』 は機能がよく似ていますが、複数の行がある文字列を対象に正規表現を行った場合、『^』 は改行の直後にもマッチしますが、『\A』 は文字列の先頭にしかマッチしません。

また、『$』は改行の直前にもマッチしますが、『\Z』は文字列の末尾にしかマッチングしません。



◆文字クラス

また、よけいな koike 6 がマッチしてしまいました。

そこで、koike 6 には数字が入っていますので、数字があるとNGにすればいいわけです。

ですが、発想を変えて、数字以外の文字が連続するとしても同じです。


・数字以外の文字が連続の検索(サンプル04 sample04.pl)
while(<STDIN>){
   if(/^k[^0-9]+$/){
      print;
   }
}
% sample04.pl < family.txt
kazumasa murai

今度は上手く行きました。

まず、[〜]は文字クラスといって、[0-9]の場合は 0から9までの1文字にマッチします。

[^0-9]は文字クラスの中に ^が付くことによって文字クラスの否定を意味します。

文字列のアンカーの『^』とは別物です。

[^0-9]+の+は1回以上の『繰り返し』という意味です。

つまり、0-9以外の一文字の繰り返しになります。

$は末尾にマッチのアンカーの$です。


・1語の名前を検索(サンプル05 sample05.pl)
while(<STDIN>){
   if(/^\S+$/){
      print;
   }
}
% sample05.pl < family.txt
hisa

\Sも文字クラスで、空白文字以外を表します。

つまり、^\S+$ は先頭が空白文字以外で、これがかつ一回以上の繰り返しで、末尾までになります。


・3語の名前を検索(サンプル06 sample06.pl)
while(<STDIN>){
   if(/^\S+\s+\S+\s+\S+$/){
      print;
   }
}
% sample06.pl < family.txt
ni-bo- horie yasashii
nee-nee horie chottokowai

\sも文字クラスで、空白文字(空白,タブ,改行)を表します。\Sの反対です。

つまり、^\S+\s+\S+\s+\S+$ は先頭が空白文字以外で、これがかつ一回以上の繰り返した後、空白文字を一回以上の繰り返し、空白文字以外一回以上の繰り返し、空白文字を一回以上の繰り返し、空白文字以外一回以上の繰り返しで、末尾までになります。


・文字クラス一覧
    [ABC]           A,B,Cのいずれか1文字    
    [A-Z]           A〜Zまでのいずれか1文字
    [A-Za-z0-9]     A〜Z, a〜z, 0-9までのいずれか1文字    
    [^ABC]          A,B.C以外の文字
    [^A-Z]          A〜Z以外の文字  
    \w              英数文字。[a-zA-Z0-9]と同様    
    \W              \w以外の文字
    \d              数値文字。[0-9]と同等    
    \D              \d以外の文字
    \s              空白文字(空白,タブ,改行)     
    \S              \s以外の文字
    \b              単語の区切り
    .               任意の一文字

・補足3

/koike/ だと koikesでもマッチしてしまいますが、/\bkoike\b/だと回避できます。

・補足4

\wと\Wは、アスキー系以外では機能しない場合があるらしい。




◆メタキャラクタとエスケープ

正規表現において特殊な意味を持つ文字をメタキャラクタと呼びます。

    + * ? . ( ) [ ] { } | \ $ ^

\は、メタキャラクタの本来の作用をエスケープし、

メタキャラクタ以外では書かないのと同じになります。

たとえば、


^\^ は、^という文字で始まる行にマッチ

\\ は、\自体にマッチ


また、\Qと\Eの間に挿入された文字列は全部の文字の前に \ が挿入されたものと同じです。

/\o\)\+\>/ と /\Qo)+<\E/ は同じ。


◆繰り返し
    A+              1個以上連続したA(A, AA, AAA, ...)
    A*              0個以上連続したA(  , A, AA, AAA, ...)
    A?              0または1つの任意文字(  , A, B, C, ...)
    A{5}            5回繰り返し。 AAAAAと同じ
    A{3,}           3回以上繰り返し。 AAA+と同じ
    A{3,5}          3回以上5回以下繰り返し。 AAAA?A?と同じ

◆ 最大マッチと最小マッチ

たとえば、以下のようなデータがあったとします。

<h1>Koike family</h1> <h2>Home Page</h2> <h3>By chaichanpapa</h3>

このデータからタグのみ除去してみましょう。

タグは < ではじまり、 > で終わる文字列です。

その文字列の中を「.」の任意の一文字で「*」で0回以上の繰り返しとして指定します。

ですので、以下のようなプログラムになります。

・サンプル(sample10.pl)
while(<DATA>){
      s/<.*>//g;
      print;
}
__END__
<h1>Koike family</h1> <h2>Home Page</h2> <h3>By chaichanpapa</h3>

では、実行してみましょう。

% sample10.pl

%

改行のみの表示だけになってしまいました。

実は、perlでは、パターンマッチがもっとも長い文字列とマッチする最大マッチなのです。

ですから、<h1>Koike から chaichanpapa</h3> まで削除されてしまいました。

では、タグのみ削除するにはどうしたらいいでしょう?

それには最小マッチの ? を指定します。

・サンプル(sample11.pl)
while(<DATA>){
      s/<.*?>//g;
      print;
}
__END__
<h1>Koike family</h1> <h2>Home Page</h2> <h3>By chaichanpapa</h3>

では、実行してみましょう。

% sample11.pl
Koike family Home Page By chaichanpapa

今度は、タグが除去され、上手くいきました。


・補足5

最大マッチと最小マッチは、英語(perlretut.pod)での"maximal match"と"minimal match"の訳です。

しかし、訳者によって、最長マッチと最短マッチや最多マッチと最少マッチになっていますね。

ちなみに、私は、すP派です。


◆グループ化と選択

文字列を繰り返すときは()を使ってグループ化します。

    koi(ke)+        koike, koikeke, koikekekeなどにマッチします。
     
    いくつかのパターンのどれかにマッチさせるときは | を使います。
    (選択はパフォーマンスがあまり良くないとのことです。)

    macha|yachu     machaかyachuにマッチします。
    koike(X|Y)      koikeXかkoikeYにマッチします。

◆カッコを使った記憶

また、グループ化した部分は後から参照することができます。

これを後方参照といい、 同じ正規表現内で後方参照を行うには、\1, \2... を用います。

    /(koike)\1/    koikeが2回連続する文字列にマッチします。

また、正規表現外で後方参照を行うには、マッチ特殊変数 $1, $2... を用います。

$str =~ /^(k.+) (c.*)$/i;
print $1, "\n"; # koikeと表示される
print $2, "\n"; # chaichanと表示される

◆マッチ特殊変数

マッチ特殊変数には、$1,$2,・・・の他に、$` , $& , $'等があります。

これらは、パターンマッチしたときに「マッチする前までの文字列」、「マッチした文字列」、「マッチした後の文字列」が各々、$` , $& , $' に格納されます。では、プログラムで確かめてみましょう。


サンプル sample14.pl
  $n = 0;
  while(<STDIN>){
        chomp;
        / \S+ | /;
        ++$n;
        print "*** $n ***\n";
        print "AAA: $`\n";
        if($& ne " "){
           print "BBB:" . substr($&, 1, length($&) -2) . "\n";
        } 
        print "CCC: $'\n";
        print "\n";
  }
% cat family3.txt
macha koike
sayuri koike chaichan
%
%
% sample14.pl < family3.txt
*** 1 ***
AAA:macha
CCC:koike

*** 2 ***
AAA:sayuri
BBB:koike
CCC:chaichan

まず、chompは $_ の末尾の改行コードを切り落とします。

/ \S+ | /; は「左右に空白を持つ非空白1文字以上か、または、1文字の空白」のマッチです。

つまり、今回の場合は、 *** 1 ***は「1文字の空白」のマッチで、 *** 2 ***は「左右に空白を持つ非空白1文字以上か」にマッチします。

そして、$` と $& と $' に各々の値が格納されます。尚、$&には前後にスペースが入っていますので、substr($&, 1, length($&) -2)で削除します。


◆置換処理

置換演算子(s///)を用いると、文字列の置換を行うことができます。

my $str = 'koike sayuri';
$str =~ s/(koike) sayuri/$1 chaichan/; # $strは 'koike chaichan' になる
print $str, "\n";

・修飾子

以下の修飾子を指定することにより、パターンマッチの振る舞いを変えることができます。

・i修飾子

i修飾子は、正規表現がアルファベットの大文字小文字を区別せずにマッチするようにするために指定します。

m/^chaichan$/i; # chaichanにもChaichanにもCHAICHANにもChAichanにもマッチする。

・s修飾子
#「.」が改行にもマッチするようになる
my $str = "aaa bbb\nccc ddd";
print "No Match1\n" if ($str !~ /bbb.*ccc/);
print "Match1\n"    if ($str =~ /bbb.*ccc/s);

・m修飾子
my $str = "aaa bbb\nccc ddd";
print "No Match2\n" if ($str !~ /^ccc/);
print "Match2\n"    if ($str =~ /^ccc/m);

・x修飾子

正規表現内の空白や改行が無視され、「#」以降はコメントとして扱われます。

# 1と出力
print 1 if 'Chaichan' =~ /
C
h
a
i
# コメント
c
h
a
n
/x;

・e修飾子

以下はあまり意味がないプログラムですが、3回『e』しています。

my $str = "hello world";
$str =~ s/\w+/subx()/eeeg;
print $str;

sub subx {
    return 'suby()';
}
sub suby {
    return 'subz($&)';
}
sub subz {
    ucfirst($_[0]);
}

C:\perltest>perl reg_e.pl
Hello World

・g修飾子

連続して何回もマッチの gですが、上記で『s/\w+/subx()/eeeg』を『s/\w+/subx()/eee』にすると、表示は『Hello world』となり、worldはそのままで、Helloだけ『h』が『H』になり、連続しなくなります。

逆にいうと、g修飾子を指定すると連続して何回もマッチするわけです。


・o修飾子

変数展開が最初の1回だけ行われます。

逆にいうと、o修飾子を指定しない場合は、毎回変数展開される。

my $str = "aaa bbb\nccc ddd";
my $regex = 'aaa';
for (1..10) {
    print "Match3\n" if ($str =~ /$regex/o);
}

◆拡張構文

Perlには、以下のような拡張構文があります。

拡張構文は、キャプチャ(カッコを使った記憶)を行わないため、マッチした部分を正規表現の中で\1、\2のように参照したり、後から$1、$2のような変数で参照したりすることができません。


以下は、拡張構文のサンプルです。すべてマッチします。

$bbb = '東京都庁';
$ccc = 'とうきょう都庁';
print "Match1", "\n" if ($bbb =~ /東京(?=都庁)/);  # 東京の後に都庁が続いている東京にマッチ
print "Match2", "\n" if ($bbb =~ /東京(?!議会)/);  # 東京の後に議会が続いていない東京にマッチ
print "Match3", "\n" if ($bbb =~ /(?<=東京)都庁/); # 東京の後に都庁が続いている都庁にマッチ
print "Match4", "\n" if ($ccc =~ /(?<!東京)都庁/); # 東京でないの後に都庁が続いている都庁にマッチ

ちなみに、拡張構文の「東京(?=都庁)」と普通構文の「東京(都庁)」は同じ結果になりますが、すべての拡張構文には後方参照がありません。

また、拡張構文では検索文字にパターンマッチ修飾子(imsx)が埋め込めます。

# 普通構文
$ddd = 'Tokyo';
if (/$ddd/i) {
  print "$ddd\n";
}
# 拡張構文
$ddd = "(?i)Tokyo";
if (/$ddd/) {
  print "$ddd\n";
}
◆ 正規表現初心者卒業

上記がマスター出来たら、とりあえず、正規表現初心者卒業です。

しかし、正規表現は奥が深く、また、Perlが独自に拡張しています。

ですので、まだまだ、正規表現を極めようという人は、とりあえず以下で勉強をしてみてください。

再帰的な正規表現や正規表現の中にPerlコードを記述できたりと、高度なテクニックが書いてありますよ。


◆ 参考リンク

【その13】リファレンスについて

普通、リファレンスといえば、一覧の機能参照のことですが、Perlでリファレンスといえば、言語仕様のアドレス参照のことなのです。

まぁ、PerlでのリファレンスをC言語でいえば、アドレス演算ができないポインタのようなものなのです。


リファレンスの利用場面は、私が思いつくところでは以下のケースです。


◆多次元配列を処理するケース
my $array_ref1 = \@array; 

配列変数の@の前に、\をつけると、配列のリファレンスが取得できます。

上記は、配列@arrayのリファレンスを$array_ref1へ格納しています。

また、無名配列のリファレンスを格納することもできます。

my $array_ref2 = [ 1, 2, 3, 4 ]; 

リストを [ ] でくくると、無名配列になり、そのリファレンスを$array_ref2へ格納しています。


つぎに、リファレンスから元の値を取得することをデリファレンスといいます。

my $array_ref2 = [ 1, 2, 3, 4 ]; 
print $array_ref2->[3]; #デリファレンス

ちなみに、『->』は矢印演算子といい、リファレンスをデリファレンスします。


補足:リファレンスの元をリファレントいいます。

つまり、$array_ref1がリファレンスで、\@arrayがリファレントです。


この機能を利用すると多次元配列の処理が可能です。

@a = ( [ qw(00 01 02) ],
       [ qw(10 11 12) ],
       [ qw(20 21 22) ]);
for $i (0 .. $#a) {
    for $j (0 .. $#{$a[$i]}) {
        print '$a[' . $i . '][' . $j . ']=' . $a[$i][$j] . '   ';
    }
    print "\n";
}

尚、上記では『->』矢印演算子がありませんが、大括弧(ブラケット)や中括弧(ブレース)の間にはさまれた矢印は省略可能なのです。


◆関数をリファレンスでコールするケース

関数のリファレンスも配列と同様にできます。

sub01("aaa");   # 普通にコール
$sub = \&sub01;
$sub->("aaa");  # リファレンスでコール
sub sub01 {
    print "--- sub01 $_[0]---\n";
}

『$sub = \&sub01;』で関数のリファレンスを格納して、『$sub->("aaa")』でコールしています。


◆関数の引数へ配列を渡すケース

Perlでの関数の引数はリストです。

引数に配列変数を渡すとリストに展開されてしまい、普通は上手く配列変数を渡せません。

そこで登場してくるのが配列変数のリファレンスです。

リファレンスなら、上手く配列変数を渡せるのです。

my @bbb = ("bbb", "ccc", "ddd");
my @xxx = ("xxx", "yyy", "zzz");
sub02("aaa", \@bbb, \@xxx);  
sub sub02 {
    print "--- sub02 $_[0]---\n";
    print "--- sub02 $_[1]->[0]---\n";
    print "--- sub02 ${$_[1]}[1]---\n";
    print "--- sub02 $_[1][2]---\n";
    print "--- sub02 $_[2][0]---\n";
    print "--- sub02 $_[2][1]---\n";
    print "--- sub02 $_[2][2]---\n";
}

◆ 関数のリターン値にするケース

関数のリターン値でblessしたリファレンスが返された場合、それは、他言語でいうオブジェクトと同じ感じになるのです。

my $date = DateString->new();
print $date->to_string, "\n";

package DateString;
sub new {
    my $class = shift; # 第一引数は、クラス名が渡される。
    my $time = shift || time();
    return bless { time => $time }, $class; # blessしたリファレンスを返す。
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}

【その14】use宣言について

Perlをやり始めると、requireはすぐ分かるんだけれど、useって謎だなぁって思いますね!

今回は、そんなuseの謎に迫ります。


はじめに、requireは、C言語でいう%includeと同じで別ファイルにあるソースを実行時にあたかも自ソースとして読み込みます。

つぎに、useは、実行前(コンパイル時)にあたかも自ソースとして読み込みます。


実行前というのは、Perlではコマンド起動時にコンパイルしてから実行するという2段階方式になっているのです。

つまり、useはコンパイルに実行され、requireはコンパイルに実行されるのです。


そして、読み込んだソース(モジュール)にpackage宣言がない場合、useとrequireでは、これ以外の違いはありません。

しかし、モジュールにpackage宣言があると、ちょっとややっこしくなるのです。


まず、モジュールでなく、メインソースの方には、package宣言がありませんが、実は、デフォルトでmainというpackage名になっています。

一方、モジュールの方は、package宣言でpackage名をmain以外で指定すると、当然ですがメインソースとは別のpackage名になりますね。


しかし、別のpackage名になっても、useには他モジュールを、以下ようにあたかも自モジュール(mainモジュール)にあるようにする仕組みがあるのです。

いきなり、importが出てきますが、これは、Moduleモジュール内でExporterモジュールを継承していて、Exporterモジュール内のメソッドなのです。


◆サンプル
・mainモジュール
#use Module;
BEGIN { require Module; Module->import;} # use Module; と等価
print sumx(5,3),"\n"; # Moduleモジュールのsumx関数があたかも自関数のように使える

・Moduleモジュール
package Module;
use base Exporter;          # use Exporter; our @ISA = qw(Exporter); と等価
our @EXPORT = qw(&sumx);
sub sumx {
 return $_[0]+$_[1]; # 渡された引数2つを加えて返す処理
}
1;

◆補足

Moduleモジュールでは、『use base Exporter』でExporterを継承して、『our @EXPORT = qw(&sumx);』でsumx関数をエクスポートしています。

mainモジュールでは、『Module->import;』でModuleモジュールでエクスポートしたsumx関数をインポートしています。

【その15】blessについて

useやモジュールとリファレンスが理解出来てくると、blessが気になってきますね!

今回は、そんなblessの謎に迫ります。


blessを一言でいうと、リファレンスとパッケージを紐付けます。


たとえば、以下を見てください。

use strict;
use warnings;

my %test_HASH = (aaa => 'XXX', bbb =>'YYY');
my $test = bless \%test_HASH, 'package01';  # リファレンスとパッケージを紐付け

print '-->', $test->{aaa}, '<--', "\n";
$test->test01(3);
print '-->', $test->{aaa}, '<--', "\n";

package package01;
sub test01 {
    print "第1引数は$_[0], 第2引数は$_[1]です。", "\n";
    my $obj_self = shift;
    $obj_self->{aaa} = 'ZZZ';
}

『my $test = bless \%test_HASH, 'package01';』で、%test_HASHのリファレンスとpackage01のパッケージを紐付けています。

そして、blessのりターン値が%test_HASHのリファレンスなのですが、だだのリファレンスでなく、blessで紐付けられたpackage01パッケージも含まれるのです。

なので、『$test->test01(3);』のようにpackage01パッケージのtest01サブをコールすることが出来るのです。


コールする時、『->』矢印演算子を使うとtest01サブでは、自動的に第1引数が自リファレンスになるのです。

なので、『$obj_self->{aaa} = 'ZZZ';』でリファレンスからもとのハッシュ変数にアクセスして書き換えが可能なのです。


結果的にリファレンスが、ハッシュ変数(プロパティ)とサブルーチン(メソッド)を持つことになるのです。

プロパティとメソッドと言えば、そう、オブジェクトになるのですね…これが!!

【その16】Perlでのオブジェクトについて

えーと、前回ご説明しましたが、Perlでは一つのパッケージが一つのクラスになります。

つまり、パッケージ名がクラス名になるのです。


また普通、クラスには、オブジェクトを構築するコンストラクタがあります。

そして、コンストラクタでblessしたリファレンスにクラス名を紐付けてリターン値にして、それを変数に格納するとその変数がインスタンスになります。


って、文章で説明しても分かり辛いので、以下のソースを見て感じとってください。

use strict;
use warnings;

print "\n", '◆ポイント1の例(パッケージ名(クラス名)が第1引数)', "\n";
package00->test00(3);

package package00;
sub test00 {
    print "第1引数は$_[0], 第2引数は$_[1]です。", "\n";
    my $class = shift;
    print "第1引数は $class でクラス名になります。\n"
}


print "\n", '◆ポイント2の例(blessリファリンス(オブジェクト)が第1引数---', "\n";
my %test_HASH = (aaa => 'XXX', bbb =>'YYY');
my $test = bless \%test_HASH, 'package01';

print '-->', $test->{aaa}, '<--', "\n";
$test->test01(3);
print '-->', $test->{aaa}, '<--', "\n";

package package01;
sub test01 {
    print "第1引数は$_[0], 第2引数は$_[1]です。", "\n";
    my $obj_self = shift;
    $obj_self->{aaa} = 'ZZZ';
    print "第1引数は $obj_self  でオブジェクトになります。\n"
}


print "\n", '◆ポイント3の例 オブジェクト例(委譲)---', "\n";
my $obj_package02 = package02->new(); # newはオブジェクトコンストラクタ
                                      # $obj_package02はインスタンス
print '-->', $obj_package02->{bbb}, '<--', "\n";
$obj_package02->test02(4);            # オブジェクトのメソッド起動
print '-->', $obj_package02->{bbb}, '<--', "\n";

package package02; # パッケージは、Perlではクラスになる
sub new {
    print "第1引数は$_[0]でクラス名です。", "\n";
    my $class = shift;
    my %test_HASH = (aaa => 'XXX', bbb =>'YYY');
    return bless \%test_HASH, $class;
}
sub test02 {
    print "第1引数は$_[0], 第2引数は$_[1]です。", "\n";
    my $obj_self = shift;
    $obj_self->{bbb} = 'ZZZ';
    print "第1引数は $obj_self  でオブジェクトになります。\n"
}

【その17】Perlでのオブジェクト指向について

Perlは元々は、オブジェクト指向言語ではありません。

しかし、柔軟な言語仕様のPerlでは、オブジェクト指向言語のように振る舞うことも可能なのです。


普通、オブジェクト指向プログラミングでは、以下の要素が必要です。


ということで、カプセル化とオーバーロード以外は、大丈夫なのです。

以下に、クラス、コンストラクタ、継承、多態性、オーバーライドを使用したサンプルを書いてみました。


◆サンプル
use strict;
use warnings;

my $obj;
my $hiki = shift;

if ($hiki eq '1') {
    $obj = Otokonoko->new();
}
else {
    $obj = Onnanoko->new();
}
print $obj->getName(), "\n";
$obj->shumi();


package Person;
sub new {
    my $class = shift;
    my $self = {
        Name => $class,
    };
    return bless $self, $class;
}
sub getName {};


package Otokonoko;
use base 'Person';
sub getName {
    my $self = shift;
    return $self->{Name};
}
sub shumi {
    print "バスケ\n";
}


package Onnanoko;
use base 'Person';
sub getName {
    my $self = shift;
    return $self->{Name};
}
sub shumi {
    print "ケーキ作り\n";
}

◆実行結果
C:\perltest>perl tatai.pl 1
Otokonoko
バスケ

C:\perltest>perl tatai.pl 2
Onnanoko
ケーキ作り

◆ おすすめのPerl本

■ おすすめのPerl本

■ すぐわかるPerl

この本、凄く難解なPerlを分かり易くやさしく説明をしていて、まさに『すぐわかるPerl』です!

Perl入門に最適な本だと思います。この本から入れば、たぶん、Perlで悩まなくてすみます。


すぐわかるPerl

■ 初めてのPerl

先日、ご紹介した『すぐわかるPerl』のつぎにこの本を読むと吉です。

『初めての』といいながら、ちょっとレベル高いです。

■ 続・初めてのPerl 改訂版

『初めてのPerl』の次ぎに読むと吉です。

結構いいですが・・・、初心者にはちょっと難しいかもです。

■ 結城浩のPerlクイズ

この本には、ちゃいちゃんパパの小話しが載っています(謎)。

ある程度、Perlを理解している人には、たまらない内容になっています。さすが結城先生だな!

結城浩のPerlクイズ

■ 新版Perl言語プログラミングレッスン入門編

実は、私はまだ読んでいませんが、結城先生の本なので良くないはずがありません。

新版Perl言語プログラミングレッスン入門編

■ CGI&Perlポケットリファレンス (Pocket reference)

この本は、非常に役に立ちます。ちょっと調べるのに最適です。サンプルも説明も的を射ています。

CGI&Perlポケットリファレンス (Pocket reference)

■ Perlベストプラクティス

一読の価値有りだと思います。

Perlベストプラクティス

■ プログラミングPerl〈VOLUME1〉

ご存知、Perl本の聖書、ラクダ本(上)です。

■ プログラミングPerl〈VOLUME2〉

ご存知、Perl本の聖書、ラクダ本(下)です。

◆ おわりに

最後に、本ページが、何かのお役に立てれば幸いです。

尚、ご感想、ご意見、誤字、脱字、間違い等がありましたら遠慮なくPerlノート掲示板へご指摘ください。

HTML/ CSS/ CGI-Perl/ JavaScript/ JavaApplet/ AccessUp/ Internet/ EnglishLearn/ ちゃいちゃん天使/ 天使メッセージ/ 飯田ワールド/ 結城ワールド/ プロフィール/ WEB相談室/ WEBアンテナ/ WEBリーダー/ 燈明日記/ 法華経ブログ/ yahoo