TOP

Perl入門

目次

はじめに

目次へ戻る

動作確認

目次へ戻る

対象者

目次へ戻る

Perlとは

Perlは、Practical Extraction and Report Languageの略称であり、Report Languageといわれるように拡張された正規表現によりテキスト処理に優れています。

2004年7月8日現在、最も利用されているインタプリタ言語のひとつです。現在のバージョンは5.8.xでありUnicodeのサポートなどが上げられます。次期バージョンのPerl6では、VM(Virtual Machine)などの機能が加えられる予定です。

CPANなどの世界的なコニュニティサイトも存在しています。時に"Write Only"と呼ばれPerlの可読性に悩まされる事もあります。これはRubyと対比してみると理解出来ると思います。またオブジェクト指向機能は、Pythonと同様Perlのバージョン5から追加されたため一般の入門サイトなどはPerlを構造型言語として紹介してる傾向があります。

目次へ戻る

コメント

# シャープがコメントです。

 

目次へ戻る

構造

#!/usr/bin/perlを記述しなければなりません。

 

目次へ戻る

コーディング規約

ありません。

 

目次へ戻る

ハローワールド

#!/usr/bin/perl

# comment

# Hello World
# variable define must use duller mark($) and semi corron
$name="perl";

# space with statemeta
$name = "Perl";

print $name;
print "$name\n";
print "Hello" . $name . "World\n"; 

 

目次へ戻る

データ形式

文字列か数値であるかはインタプリタが解析してくれます。

#!/usr/bin/perl
$name="perl";

# space with statemeta
$name = "Perl";

print $name;
print "$name\n";
print "Hello" . $name . "World\n";

$num=100;
print $num . "\n";
print $num . '\n'; 

配列

配列の定義には@マークを使い、参照は$マークを使います。

#!/usr/bin/perl

# Array
@name_list=("PerlMan","JavaMan","CGeek");
print "\n";
print $name_list[0] . "\n";
print $name_list[1] . "\n";
print $name_list[2] . "\n";
 

ハッシュ(連想配列、Javaのjava.lang.Map)

#!/usr/bin/perl

# Hash (Map Object in Java)
# Key => value
# Key require String type!
%program_language=(
"Perl"=> 5.8,
"Java"=> 1.4,
"C#"=> 1.1
);

print $program_language{"Perl"},"\n";

%programer = (
"Java"=> "James Gosling",
"Perl"=> "Lelly Wall",
"C"=> "K & R"
);

print $programer{"C"}, "\n";
サンプル2


#!/usr/bin/perl
%hash_obj= (
        "Perl"=>"Larry Wall",
        "Java"=>"James Gosling",
        "C"=>"K&R"
);

print "***** keys\n";
foreach $key (keys %hash_obj) {
        print "KEY=$key\n";
}

print "***** values\n";
foreach (values %hash_obj) {
        print "VAL=$_\n";
}

print "***** delete\n";
foreach $key (keys %hash_obj) {
        if ( $key =~ /C/ ) {
                delete $hash_obj{$key}
        }
}

print "***** elements\n";
while (($key, $value) = each %hash_obj) {
        print "$key=$value\n";
}

print "**** exists\n";
foreach $key (keys %hash_obj) {
        if ( exists $hash_obj{"Perl"} ) {
                print "exist!,$key\n";
                exit 0;
        }
} 

 

リファレンス

メモリのアドレスを操作できる機能です。C言語のポインタほどの汎用性はありませんが、アドレス操作が可能な言語のため非常に強力な実装が可能です。\記号でリファレンスを表します。

#!/usr/bin/perl

printf "refref";
$word = "A";
$ref_word = \$word;
$refref = \$ref_word;
print $$$refref, "\n";

print ref $refref, "\n";
print ref $ref_word,"\n";
print ref $word, "\n";

 

目次へ戻る

演算子



#!/usr/bin/perl

#operation
print 2+1, "\n";
print 1-2 ,"\n";
print 7/3 ,"\n";
print 1%2 ,"\n";
print 2**4 ,"\n";
# string
$val='a'.'b'."\n";
print $val;

# repetition operator.
$val2='----+----*';
print $val2 x 8;
print 'hello'."\n";
print $val2 x 8; 

 

目次へ戻る

制御構造

分岐

#!/usr/bin/perl

# diverge (like C)
# numenic 
$num = "100";
if ($num ne "100") {
print "no\n";
} else {
print $num,"yes!\n";
}

# string
$val = 100;
if ($val == 100) {
print "$val\n";
}
# repetition 
$cnt = 0;
while ($cnt < 10) {
$cnt = $cnt + 1;
}
print $cnt , "\n"; 

 

反復

#!/usr/bin/perl
# iterator
@name_list=("PerlMan","JavaMan","CGeek");
foreach $item (@name_list) {
    print $item, "\n";
}

# 上記のサンプルをデフォルトの変数$_で実行した場合。
# iterator with The default implicite valirable $_ mark.
# but you do not have to use this mark for maintenance.
foreach (@name_list) {
    print $_, "\n";
}

# zero is false in Perl
$boolean=0;
while ($boolean) {
    print "in wihle statement!\n"
} 

 

目次へ戻る

データ処理

ソート

<=>とsort関数を使ってswapが可能です。
#!/usr/bin/perl
# sort
@test_ary=(
1,2,3,4,5,6,7,8,9
);
@tmp = sort {$a <=> $b} @test_ary;
foreach $item (@tmp) {
    print $item,"\n";
}

@tmp = sort {$b <=> $a} @test_ary;
foreach $item (@tmp) {
    print $item,"\n";
}

置換

暗黙変数$_に対してs/x/y/を使って置換が出来ます。

#!/usr/bin/perl
# substitute (translate)
$_="satoshi okita";
s/okita/atiko/;
print $_, "\n";
 

分割

splitコマンドで分割が出来ます。

#!/usr/bin/perl

# /etc/passwd
# String sepalate
$camma_sep="aa:bb:cc"; # variable
@camma_ary= split /:/, $camma_sep;
foreach $item (@camma_ary) {
print $item, "\n";
}
 

結合

joinで結合が出来ます。

#!/usr/bin/perl@camma_sep=("Perl","Ruby","Python");$join_result= join "-", @camma_sep;print $join_result;

 

目次へ戻る

正規表現

=~を利用してデータの正規表現が可能です。

#!/usr/bin/perl
# pattern match


@name_list=("PerlMan","JavaMan","CGeek");

# pattern match (requler expression)
print "pattern match sample 1";
foreach $item (@name_list) {
    if ($item =~ /Java/) {
        print $item,"\n";
    }
}

print "pattern match sample 2";
foreach $item (@name_list) {
    if ($item =~ /.*/) {
        print $item,"\n";
    }
}

print "pattern match sample 3";
# use default mark
foreach (@name_list) {
    if (/Java/) {
        print $_,"\n";
    }
} 
目次へ戻る

関数

暗黙変数$_をつかって引数を取得します。また関数は&を利用して呼び出します。

#!/usr/bin/perl
# subrouting
sub add {
    $result = $_[0] + $_[1];
    return $result;
}

print &add(1,1);


再帰処理のサンプル

#
# directory search.
#
# $Date: 2005-09-18 12:18:53 +0900 (Sun, 18 Sep 2005) $
# $Revision: 1063 $
# $Id: ls.pl 1063 2005-09-18 03:18:53Z s-okita $

print "BEGIN\n";

sub ls {
        # arguments
        local($current_directory) = @_;
        print "current:$current_directory\n";
        
        # directory open,close
        opendir(DISCRIPTER_DIR, $current_directory) || die "error open";
        
        local(@file_list) = readdir(DISCRIPTER_DIR);
        
        closedir(DISCRIPTER_DIR);
        
        # Retreave
        foreach(@file_list) {
                $file = $_;

                if ( -d "${current_directory}" . "\\$file" ) {
                        print "Dir\t$file\n";
                        if (( "." ne $file ) && ( ".." ne $file )) {
                                # Recursive
                                & ls("${current_directory}" . "\\$file");
                        }       
                } else {
                        print "File\t$file\n";
                }
        }
}

& ls(".");

print "END";
 

目次へ戻る

 

引数

#!/usr/bin/perl

printf "@ARGV";
$argc = $#ARGV + 1;
printf "$argc.....";
printf $ARGV[0];
printf shift @ARGV;

目次へ戻る

FORMAT

Perlは帳票印刷用にFORMATという機能があります。Fortran,BASICなど昔から存在する言語は言語仕様として帳票機能があります。

以下のように@記号で始まる置換文字列ををフィールドホルダと呼びます。

#!/usr/local/bin/perl

# format statement.
# format format_name =
# fieldline
# value_one, value_two
# .

# format definition
# '@<' is named 'filedholder' that replace value line like $name, $address.
#
format ADDRESS =
================================================================================
| @<<<<<<<<<<                                                                  |
$name
| @<<<<<<<<<<                                                                  |
$address
================================================================================
.


$name=satoshi;
$address=japan;

# call format
# write <filehandle>
# you msut define filehandle as format define.
open(ADDRESS, ">/dev/stdout") || die "error open";
write ADDRESS; 

 

左寄せ、中央寄せ、右寄せ

#!/usr/local/bin/perl

format LCR =
********************************************************************************
* name : @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$name
* age  : @|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$age
* date : @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$date
********************************************************************************
.

$name="okita";
$age="26";
$date="2004/09/06";

open(LCR, ">/dev/stdout") || die "error open";
write LCR;
 

 

数値フィールド

#!/usr/local/bin/perl
# number format sample

format NUM =
--------------------------------------------------------------------------------
float value: @#####.##
$val
--------------------------------------------------------------------------------
.

$val=999.99;

open(NUM,">/dev/stdout") || die "error open";
write NUM;

 

マルチラインフィールドフォルダ

#!/usr/local/bin/perl

format MULTI_HOLDER =
--------------------------------------------------------------------------------
@*
$data
--------------------------------------------------------------------------------
.

$data=" Perl\n Larry Wall\n Light Weight Language";

open(MULTI_HOLDER, ">/dev/stdout") || die "error open";
write MULTI_HOLDER;
 

詰め込み形式フィールド

~~(チルダ2つ)は、抑制指示子(suppression indicator)と呼び、フォーマット1行をn件のデータに対応するために利用します。
[s-okita@stoc perl]$ cat filled_field.pl
#!/usr/bin/perl

format FILLED_FIELD =
CATEGORY:@<<<<<<<<<< NAME:^<<<<<<<<<<
         $category        $name
~~                   NAME:^<<<<<<<<<<
                          $name
.

open(FILLED_FIELD, ">/dev/stdout") || die "can not create field.";

$category = "LANGUAGE";
#         1234567890
$name =  "Java      ";
$name .= "Perl      ";
$name .= "COBOL     ";

write(FILLED_FIELD);
[s-okita@stoc perl]$ perl filled_field.pl
CATEGORY:LANGUAGE    NAME:Java
                     NAME:Perl
                     NAME:COBOL
 

 

目次へ戻る

CPAN(Comprehensive Perl Archive Network)

Comprehensive(包括的な) Perlモジュール集

CPAN(Comprehensive Perl Archive Network)

 

目次へ戻る

perlcc

 

目次へ戻る

モジュール

ライブラリをPerlではモジュールと呼びます。

標準ライブラリのIO::Socketを使ってみます。

#!/usr/bin/perl
use IO::Socket;
$host="127.0.0.1";
$port=80;

print "scan start\n";

$socket = IO::Socket::INET->new(PeerAddr => $host,
                                        PeerPort => $port,
                                        Proto => 'tcp',);

print "$socket";

$socket->close();
print "scan end\n";
 

 

ライブラリ化 require

Main.plからMyPerlLib.plに作成したhello_prin関数を呼び出します。注意点は、requireされる側のプログラム(MyPerlLib.pl)は最後に1をつける必要があります。

[s-okita@localhost perl]$ cat MyPerlLib.pl
package MyPerlLib;

sub hello_print {
        print "hello world\n";
        return 0;
}
1
[s-okita@localhost perl]$ cat Main.pl
require './MyPerlLib.pl';

&MyPerlLib::hello_print();
[s-okita@localhost perl]$ perl Main.pl
hello world
 
目次へ戻る

その他

perl.com O'REILLY社のPerl言語のサイトで基本的な情報はすべて手に入ります。

 

目次へ戻る

ワンライナー

置換 s

-i バックアップ. -p ループ, -e 実行 "s/置換前/置換後/ig" ファイル名

igは、大文字小文字を意識しないiオプションと列の全てが対称になるgオプション

E:\Perl\eg>perl -i.bak -p -e "s/print/zzz/ig;" example.pl

E:\Perl\eg>perl -i.bak -p -e "s/ほげ/ふが/ig;" ほげ.pl
目次へ戻る

最後に

 今回、Perl入門を体験しながら書いてみましたが、perl.comなどを参照した時に、他の言語に比べて、可読性が良いとはいえない理由が理解できました。今回の入門では複雑な記述はしていませんが、Perlは記号に多くの意味をもたせている事が原因だと思います。またJavaやC#のように言語とセットでコーディング規約が付いていないため、一般の開発者は1行に多くの処理が記述してしまう傾向があるようでした。

しかし、これほどまでに世界中で使われているのは、そのような言語体系であっても習得の容易性、情報量、言語としての高い完成度があると思います。個人的には1度は触れておかなければならない言語だとおもいました。

 

目次へ戻る


イバラキングへのリンク Get Firefox Valid XHTML 1.1 Apple Darwinへのリンク