Perlプログラミング入門ガイド

はい、承知いたしました。Perlプログラミング入門ガイドの詳細な記事を記述します。約5000語を目指します。


Perlプログラミング入門ガイド:テキスト処理とシステム管理の強力な味方

はじめに:Perlとは何か?なぜ今Perlを学ぶのか?

プログラミングの世界には数多くの言語が存在します。Python、Java、C++、JavaScriptなど、それぞれが異なる得意分野を持ち、様々な目的で利用されています。その中でも「Perl(パール)」は、特にテキスト処理、システム管理、Web開発(特にCGI)、そして近年ではバイオインフォマティクスなどの分野で、長年にわたり重要な役割を果たしてきました。

Perlは1987年にラリー・ウォール(Larry Wall)によって開発されました。「Practical Extraction and Report Language」(実用的な抽出とレポート作成言語)という名前の通り、その設計思想の中心には、大量のテキストデータから必要な情報を抽出し、整形してレポートを作成するといったタスクを効率的に行うことがありました。その柔軟性と強力なテキスト処理能力から、「インターネットの配管工(plumber of the internet)」とも呼ばれ、初期のインターネットの発展を支えた言語の一つです。

Perlの大きな特徴として、「There Is More Than One Way To Do It」(TIMTOWTDI: 物事をなす道は一つではない)という哲学があります。これは、同じ処理を実現するために多様な書き方が許容されることを意味します。この柔軟性は、熟練したプログラマーにとっては簡潔で強力なコードを書くためのツールとなりますが、初心者にとっては「なぜこんなにたくさんの書き方があるのか?」と混乱の原因になることもあります。しかし、基本的な書き方をしっかり学べば、この柔軟性は大きなメリットとなります。

では、なぜ現代においてPerlを学ぶ価値があるのでしょうか?
確かに、Web開発のフロントエンドやバックエンドではJavaScriptやPython、Rubyなどが主流になっている側面もあります。しかし、Perlは今も多くの場面で現役で使われています。

  1. 既存システムの保守・運用: 長く運用されているシステムにはPerlで書かれたものが多数存在します。これらのシステムの保守や機能追加を行うためには、Perlの知識が不可欠です。
  2. システム管理・自動化: テキストファイルの設定変更、ログ解析、定期的なバッチ処理など、システム管理の多くのタスクはPerlの得意分野です。シェルスクリプトだけでは難しい複雑な処理も、Perlなら柔軟に記述できます。
  3. テキスト処理・データ解析: 大量の構造化されていない、あるいは半構造化されたテキストデータを扱うタスク(ログ解析、データのクリーニング、レポート生成など)において、Perlの強力な正規表現とテキスト処理関数は今も非常に強力です。
  4. 特定の分野(バイオインフォマティクスなど): バイオインフォマティクス分野では、DNAやタンパク質の配列データといった大量のテキストデータを扱うことが多いため、Perlが広く利用されています。
  5. CPAN(包括的Perlアーカイブネットワーク): PerlにはCPANという巨大なライブラリの宝庫があります。世界中の開発者によって作られた高品質なモジュールが公開されており、様々な機能(ネットワーク通信、データベース連携、XML/JSON処理など)を簡単にプログラムに取り込むことができます。これはPerlの大きな強みの一つです。

このように、Perlは過去の遺物ではなく、特定の領域で今もその能力を発揮し続けている実用的な言語です。特に、コマンドラインでの作業やテキスト処理が多いエンジニアにとって、Perlのスキルは強力な武器となるでしょう。

この入門ガイドでは、Perlプログラミングの基礎から応用までを体系的に学びます。Perlのインストール方法から始め、基本的な文法、変数、制御構造、データ構造(配列、ハッシュ)、サブルーチン、ファイル入出力、そしてPerlの真骨頂ともいえる正規表現までを網羅します。豊富なコード例とともに、Perlの基本的な使い方をマスターし、簡単なスクリプトが書けるようになることを目指します。

さあ、Perlの世界へ足を踏み入れましょう!

第1章:Perlを始めよう – インストールと最初のプログラム

Perlの学習を始めるには、まず開発環境を整える必要があります。多くのオペレーティングシステム(OS)には、Perlが標準でインストールされているか、簡単にインストールできる仕組みが用意されています。

1.1 Perlのインストール

  • Linux/macOS: 多くのLinuxディストリビューションやmacOSには、最初からPerlがインストールされています。ターミナルを開いて perl -v とコマンドを実行し、バージョン情報が表示されればインストールされています。もしインストールされていない場合や、最新バージョンが必要な場合は、OSのパッケージマネージャー(yum, apt, brewなど)を使ってインストールするのが最も簡単です。

    • Debian/Ubuntu: sudo apt update && sudo apt install perl
    • Fedora/CentOS/RHEL: sudo yum update && sudo yum install perl
    • macOS (Homebrew): brew install perl
  • Windows: Windowsには標準でPerlはインストールされていませんが、いくつかの配布版が提供されています。初心者には「Strawberry Perl」をおすすめします。これは、必要なライブラリ(コンパイラなど)も含まれており、インストールが比較的簡単です。

    • Strawberry Perlのウェブサイト(http://strawberryperl.com/)からインストーラーをダウンロードし、指示に従ってインストールしてください。インストール中に特に設定を変更する必要はありません。

インストールが完了したら、ターミナル(Windowsの場合はコマンドプロンプトやPowerShell)を開き、perl -v と入力してEnterキーを押してください。Perlのバージョン情報が表示されれば、インストールは成功です。

“`bash

実行例

$ perl -v

This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-thread-multi
… (以下略)
“`

1.2 最初のPerlプログラム「Hello, World!」

どのプログラミング言語でもお決まりの最初のプログラムは「Hello, World!」の表示です。Perlでもこれを書いてみましょう。

テキストエディタを開き、以下のコードを入力して hello.pl という名前で保存してください。拡張子 .pl はPerlスクリプトの慣習的なものです。

“`perl

!/usr/bin/perl

これはコメントです。この行は実行されません。

画面に “Hello, World!” を表示するプログラムです。

print “Hello, World!\n”;
“`

この短いコードについて解説します。

  • #!/usr/bin/perl: これは「シバン(Shebang)」または「Hashbang」と呼ばれるものです。LinuxやmacOSなどのUnix系OSで、このスクリプトを実行する際にどのインタープリタを使うかを指定します。ここでは /usr/bin/perl というパスにあるPerlインタープリタを使うことをシステムに伝えています。Perlの実行パスは環境によって異なる場合があるので、which perl コマンドなどで確認し、必要に応じて書き換えてください。Windowsではこの行は特に意味を持ちませんが、記述しておいても問題ありません。
  • # これはコメントです: # から行末まではコメントとして扱われます。プログラムの実行には影響せず、コードの説明などを記述するために使います。
  • print "Hello, World!\n";: これが画面にテキストを出力する命令です。print は指定された文字列を標準出力(通常は画面)に表示する関数です。"..." で囲まれた部分は文字列リテラルです。文字列の末尾にある \n は改行コードです。print はデフォルトでは改行しないため、改行したい場合は明示的に \n を付けます。セミコロン ; は文の終わりを示します。Perlでは各文の末尾にセミコロンが必要です(いくつかの例外を除く)。

1.3 スクリプトの実行

hello.pl ファイルを保存したら、ターミナルやコマンドプロンプトから実行してみましょう。

ファイルが保存されているディレクトリに移動し、以下のコマンドを実行します。

“`bash

Linux/macOSの場合 (シバン行を有効にするため、実行権限を付与することが多い)

chmod +x hello.pl # 実行権限を付与
./hello.pl # スクリプトを実行

または、シバン行に関わらずPerlインタープリタを指定して実行

perl hello.pl

Windowsの場合

perl hello.pl
“`

いずれの場合も、以下のように表示されるはずです。

Hello, World!

これで、最初のPerlプログラムの作成と実行に成功しました!

1.4 より厳密なコーディングのために:use strictuse warnings

Perlのコードを書く際には、スクリプトの冒頭に以下の2行を記述することが強く推奨されます。

“`perl

!/usr/bin/perl

use strict;
use warnings;

print “Hello, World!\n”;
“`

  • use strict;: このプラグマ(Perlに特別な指示を与えるキーワード)は、スクリプト内でいくつかの制限を有効にします。最も重要なのは、変数を初めて使う前に必ず my キーワードなどで宣言することを強制することです。これにより、タイプミスによる意図しないグローバル変数の生成などを防ぎ、バグを減らすことができます。
  • use warnings;: このプラグマは、潜在的な問題点(未初期化の変数、数値と文字列の不適切な比較など)に対して警告メッセージを表示するようにします。これらの警告はプログラムの実行を停止させませんが、バグの原因になりうる箇所を教えてくれます。

これらの2つのプラグマは、特に大規模なプログラムや、他人が読む可能性のあるプログラムを書く場合には必須と考えられます。このガイドの以降のコード例では、特に断りがない限り、この2行を含めることにします。

第2章:Perlの基本文法 – 変数とデータ型

プログラミングにおいて、値を保持したり操作したりするためには変数が必要です。Perlにはスカラー、配列、ハッシュという3つの主要な変数タイプがあります。

2.1 スカラー変数

スカラー変数 ($) は、単一の値を保持します。その値は数値、文字列、または未定義値(undef)のいずれかです。

  • 宣言: スカラー変数は、use strict; を使っている場合、初めて使う前に my キーワードを使って宣言する必要があります。
    perl
    my $name;
    my $age = 30;
    my $price = 19.80;
    my $message = "Hello, Perl!";
  • 命名規則: 変数名の最初の文字は $ で、その後に文字またはアンダースコア _ が続き、さらに文字、数字、またはアンダースコアを続けることができます。大文字と小文字は区別されます ($name$Name は別の変数です)。
  • 代入: = 演算子を使って値を代入します。
    perl
    $name = "Alice";
    $age = $age + 1; # 変数自身の値を使って計算することもできる
  • 出力: printsay 関数を使って変数の値を出力できます。sayprint と似ていますが、自動的に最後に改行を追加します(Perl 5.10以降で利用可能)。use warnings; を使っている場合は、say を使う前に use feature 'say'; を記述する必要がある場合がありますが、通常 use warnings; と同時に有効になります。

    “`perl
    use strict;
    use warnings;
    use feature ‘say’; # say関数を使えるようにする

    my $name = “Bob”;
    my $age = 25;

    print “名前: $name\n”; # ダブルクォート内では変数が展開される
    say “年齢: $age”; # sayは最後に自動で改行

    my $pi = 3.14159;
    say “円周率: $pi”;

    my $nothing; # 値を代入しないとundefになる
    say “未定義変数: $nothing”; # undefは警告が出る場合がある
    実行結果:
    名前: Bob
    年齢: 25
    円周率: 3.14159
    未定義変数: Use of uninitialized value $nothing in say at hello.pl line 11.
    未定義変数:
    ``
    未定義変数
    $nothingを出力しようとすると、use warnings;により警告が表示されます。undef` 自体は空文字列のように表示されることが多いです。

  • 数値と文字列: Perlは文脈によって数値と文字列を自動的に変換しようとします。これは便利な場合も多いですが、意図しない変換によるバグの原因にもなり得ます。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    my $num_str = “123”;
    my $number = 456;

    my $sum = $num_str + $number; # 文字列が数値に自動変換される
    say “合計 (数値として): $sum”; # 579

    my $concat = $num_str . $number; # . は文字列連結演算子
    say “結合 (文字列として): $concat”; # 123456

    my $text = “Hello”;
    my $result = $text + 10; # “Hello”は数値に変換できない
    say “数値変換できない文字列との計算: $result”;
    実行結果:
    合計 (数値として): 579
    結合 (文字列として): 123456
    Argument “Hello” isn’t numeric in addition (+) at hello.pl line 9.
    数値変換できない文字列との計算: 10
    “`
    “Hello” は数値としては0とみなされ、警告が表示されます。このような自動変換の挙動を理解しておくことが重要です。

2.2 配列変数

配列変数 (@) は、順序付けられた値のリストを保持します。

  • 宣言: my @array_name; または初期値を指定して宣言します。
    perl
    my @numbers = (1, 2, 3, 4, 5);
    my @fruits = ("apple", "banana", "cherry");
    my @mixed = (1, "two", 3.0, undef);

    括弧 () はリストコンテキストを作成します。
  • 要素へのアクセス: 配列の各要素には、ゼロから始まるインデックス(添え字)を使ってアクセスします。要素にアクセスする際は、変数名のプレフィックスが @ ではなく $ に変わることに注意してください。これは、「配列全体」を参照する @ と、「配列の中の単一のスカラー要素」を参照する $ を区別するためです。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    my @fruits = (“apple”, “banana”, “cherry”);

    say $fruits[0]; # “apple”
    say $fruits[1]; # “banana”
    say $fruits[2]; # “cherry”
    say $fruits[-1]; # 末尾の要素にアクセス (-1は末尾、-2はその前…)
    say $fruits[99]; # 存在しないインデックスにアクセスするとundefになる
    実行結果:
    apple
    banana
    cherry
    cherry
    Use of uninitialized value $fruits[99] in say at hello.pl line 11.

    * **要素数の取得:** 配列をスカラーコンテキストで評価すると、要素数を取得できます。perl
    use strict;
    use warnings;
    use feature ‘say’;

    my @numbers = (1, 2, 3, 4, 5);
    my $count = @numbers; # 配列をスカラーコンテキストで評価
    say “配列の要素数: $count”; # 5

    別の方法: scalar キーワードを使うと明示的にスカラーコンテキストにする

    my $count_explicit = scalar @numbers;
    say “配列の要素数 (scalar): $count_explicit”; # 5

    配列の最後のインデックスは $#array_name で取得できる

    my $last_index = $#numbers;
    say “配列の最後のインデックス: $last_index”; # 4
    実行結果:
    配列の要素数: 5
    配列の要素数 (scalar): 5
    配列の最後のインデックス: 4
    * **要素の追加・削除:** 配列の先頭や末尾に要素を追加・削除するための組み込み関数があります。perl
    use strict;
    use warnings;
    use feature ‘say’;

    my @items = (“A”, “B”);
    say “初期状態: @items”; # 配列全体をダブルクォート内で展開すると要素がスペース区切りで表示される

    push @items, “C”; # 末尾に要素を追加
    say “push後: @items”;

    my $last_item = pop @items; # 末尾から要素を削除し、その値を返す
    say “pop後: @items (取得した要素: $last_item)”;

    unshift @items, “Z”; # 先頭に要素を追加
    say “unshift後: @items”;

    my $first_item = shift @items; # 先頭から要素を削除し、その値を返す
    say “shift後: @items (取得した要素: $first_item)”;

    実行例:

    初期状態: A B

    push後: A B C

    pop後: A B (取得した要素: C)

    unshift後: Z A B

    shift後: A B (取得した要素: Z)

    * **スライス:** 配列から複数の要素を一度に取り出すには、スライスを使います。インデックスリストを指定します。このとき、取得されるのは要素のリストなので、受け取る変数も配列変数 `@` になります。perl
    use strict;
    use warnings;
    use feature ‘say’;

    my @letters = (“a”, “b”, “c”, “d”, “e”);

    my @subset = @letters[1, 3, 4]; # インデックス1, 3, 4の要素を取得
    say “スライス 1,3,4: @subset”; # b d e

    my @range = @letters[1..3]; # インデックス1から3までの範囲を取得 (1..3 はリスト (1, 2, 3) を生成)
    say “スライス 1..3: @range”; # b c d
    “`

2.3 ハッシュ変数

ハッシュ変数 (%) は、キーと値のペアの集合を保持します。キーは一意な文字列である必要があります。順序は保証されません。他の言語では連想配列や辞書と呼ばれることもあります。

  • 宣言: my %hash_name; または初期値を指定して宣言します。
    perl
    my %person = (
    'name' => 'Alice',
    'age' => 30,
    'city' => 'Tokyo'
    );
    # => は fat comma (太ったカンマ) と呼ばれ、左辺が自動的にクォートされるので便利
    # my %person = ( name => 'Alice', age => 30, city => 'Tokyo' ); # 同じ意味
  • 要素へのアクセス: キーを使って値にアクセスします。このときも、変数名のプレフィックスが % ではなく $ に変わります。キーは波括弧 {} で囲みます。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    my %person = (
    name => ‘Alice’,
    age => 30,
    city => ‘Tokyo’
    );

    say $person{‘name’}; # “Alice”
    say $person{age}; # 30 (キーが単純な単語ならクォートを省略できるが、明示する方が安全)
    say $person{‘gender’}; # 存在しないキーにアクセスするとundefになる
    実行結果:
    Alice
    30
    Use of uninitialized value in say at hello.pl line 11.

    * **要素の追加・変更・削除:** キーを指定して値を代入することで追加・変更、`delete` 関数で削除します。perl
    use strict;
    use warnings;
    use feature ‘say’;
    use Data::Dumper; # ハッシュの中身全体を見やすく表示するモジュール

    my %scores = ( math => 85, science => 90 );
    say “初期状態:\n” . Dumper(\%scores); # Dumperにはリファレンスを渡す

    $scores{‘english’} = 78; # 要素を追加
    say “english追加後:\n” . Dumper(\%scores);

    $scores{‘math’} = 95; # 要素の値を変更
    say “math変更後:\n” . Dumper(\%scores);

    delete $scores{‘science’}; # 要素を削除
    say “science削除後:\n” . Dumper(\%scores);
    (Dumperの出力は構造化されていますが、ここでは省略)
    * **キーと値のリスト取得:** ハッシュからキーのリスト、値のリストを取得するには `keys` および `values` 関数を使います。これらはリストを返します。
    perl
    use strict;
    use warnings;
    use feature ‘say’;

    my %capital = (
    Japan => ‘Tokyo’,
    USA => ‘Washington D.C.’,
    France => ‘Paris’
    );

    my @countries = keys %capital;
    say “国名リスト: @countries”; # 順序は保証されない

    my @cities = values %capital;
    say “都市名リスト: @cities”; # 順序は保証されない
    実行結果例(順序は実行ごとに変わる可能性があります):
    国名リスト: France Japan USA
    都市名リスト: Paris Tokyo Washington D.C.
    * **要素数の取得:** ハッシュをスカラーコンテキストで評価すると、キーと値のペアの数を取得できます。perl
    use strict;
    use warnings;
    use feature ‘say’;

    my %data = ( a => 1, b => 2, c => 3 );
    my $count = %data;
    say “ハッシュの要素数: $count”; # 3
    “`

2.4 スカラーコンテキストとリストコンテキスト

Perlでは、式が評価される「コンテキスト」によって、同じ式でも異なる結果を返すことがあります。主なコンテキストは「スカラーコンテキスト」と「リストコンテキスト」です。

  • スカラーコンテキスト: 式が単一の値(スカラー値)を返すことが期待されるコンテキスト。
    • スカラー変数への代入 (my $s = ...;)
    • スカラー値を引数にとる関数 (print $s;)
    • 算術演算、文字列演算など
    • 配列 @array をスカラーコンテキストで評価すると、要素数を返します。
    • ハッシュ %hash をスカラーコンテキストで評価すると、要素数(あるいはより複雑なハッシュの状態を示す値)を返します。
  • リストコンテキスト: 式が値のリスト(ゼロ個以上のスカラー値の並び)を返すことが期待されるコンテキスト。
    • 配列変数への代入 (my @a = ...;)
    • リストを引数にとる関数 (print @a;, push @a, ...;)
    • リストリテラル ((1, 2, 3))
    • 配列 @array をリストコンテキストで評価すると、配列の全要素をリストとして返します。
    • ハッシュ %hash をリストコンテキストで評価すると、キーと値が交互に並んだリストを返します (('key1', 'value1', 'key2', 'value2', ...))。

このコンテキストの概念はPerlの特徴の一つであり、最初は少し戸惑うかもしれませんが、配列やハッシュの要素数取得などで頻繁に出てくるため、理解しておくことが重要です。

第3章:演算子

Perlには様々な演算子があり、変数や値を操作するために使われます。

3.1 算術演算子

数値に対する演算を行います。
* +: 加算
* -: 減算
* *: 乗算
* /: 除算
* %: 剰余 (モジュロ)
* **: べき乗

“`perl
use strict;
use warnings;
use feature ‘say’;

my $x = 10;
my $y = 3;

say “加算: ” . ($x + $y); # 13
say “減算: ” . ($x – $y); # 7
say “乗算: ” . ($x * $y); # 30
say “除算: ” . ($x / $y); # 3.333…
say “剰余: ” . ($x % $y); # 1
say “べき乗: ” . ($x ** $y); # 1000
“`

3.2 文字列演算子

文字列に対する演算を行います。
* .: 文字列連結
* x: 文字列繰り返し

“`perl
use strict;
use warnings;
use feature ‘say’;

my $str1 = “Hello”;
my $str2 = “World”;

say $str1 . ” ” . $str2; # “Hello World”

say “-” x 10; # “———-”
“`

3.3 比較演算子

二つの値を比較し、真(true)または偽(false)を返します。Perlでは、真は数値の 1 (あるいは非ゼロの数値や非空文字列など) で、偽は数値の 0 (または空文字列など) で表現されます。

数値の比較と文字列の比較では異なる演算子を使います。これは、文字列としての “10” と “2” を数値として比較する場合 (10 > 2) と、文字列として比較する場合 (“10” は “2” より辞書順で後ではない) の違いに対応するためです。

  • 数値比較:

    • ==: 等しい
    • !=: 等しくない
    • <: より小さい
    • >: より大きい
    • <=: 以下
    • >=: 以上
    • <=>: 比較演算子 (spaceship operator)。左辺が右辺より小さければ -1、等しければ 0、大きければ 1 を返す。ソートなどで便利。
  • 文字列比較:

    • eq: 等しい
    • ne: 等しくない
    • lt: より小さい (lexicographically, 辞書順)
    • gt: より大きい (lexicographically, 辞書順)
    • le: 以下 (lexicographically)
    • ge: 以上 (lexicographically)
    • cmp: 比較演算子 (辞書順)。左辺が右辺より小さければ -1、等しければ 0、大きければ 1 を返す。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $num1 = 10;
my $num2 = 20;
my $str_num1 = “10”;
my $str_num2 = “20”;
my $str_a = “apple”;
my $str_b = “banana”;

say “数値比較:”;
say “$num1 == $num2 : ” . ($num1 == $num2); # 0 (偽)
say “$num1 != $num2 : ” . ($num1 != $num2); # 1 (真)
say “$num1 < $num2 : ” . ($num1 < $num2); # 1 (真)
say “$num1 > $num2 : ” . ($num1 > $num2); # 0 (偽)
say “$num1 <=> $num2 : ” . ($num1 <=> $num2); # -1

say “\n文字列比較:”;
say “$str_num1 eq $str_num2 : ” . ($str_num1 eq $str_num2); # 0 (偽)
say “$str_num1 ne $str_num2 : ” . ($str_num1 ne $str_num2); # 1 (真)
say “$str_a lt $str_b : ” . ($str_a lt $str_b); # 1 (真)
say “$str_a gt $str_b : ” . ($str_a gt $str_b); # 0 (偽)
say “$str_a cmp $str_b : ” . ($str_a cmp $str_b); # -1

say “\n数値 vs 文字列 (危険):”;
say “$num1 == $str_num1 : ” . ($num1 == $str_num1); # 1 (真) – Perlが文字列を数値に変換
say “$num1 eq $str_num1 : ” . ($num1 eq $str_num1); # 1 (真) – Perlが数値を文字列に変換
``
数値と文字列の比較演算子を間違えると、Perlが自動変換して意図しない結果になることがあるため注意が必要です。
use warnings;` を有効にしておけば、このような場合に警告が表示されます。

3.4 論理演算子

真偽値に対して論理演算を行います。
* && または and: 論理AND (両方が真なら真)
* || または or: 論理OR (どちらか一方が真なら真)
* ! または not: 論理NOT (真なら偽、偽なら真)

&&/||/!and/or/not より結合度が高く、優先順位が異なります。通常は &&/||/! を使いますが、文のような自然な流れで記述したい場合は and/or/not も使われます。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $is_sunny = 1; # 真
my $is_warm = 0; # 偽

say “天気: ” . ($is_sunny && $is_warm ? “良い” : “悪い”); # && を使う
say “天気: ” . ($is_sunny and $is_warm ? “良い” : “悪い”); # and を使う

if ($is_sunny || $is_warm) { # || を使う
say “外に出かけられる”;
}

if ($is_sunny or $is_warm) { # or を使う
say “(あるいは) 外に出かけられる”;
}

if (! $is_sunny) {
say “晴れではない”;
}
``
Perlでは
?:は三項演算子と呼ばれ、条件式の結果に応じて二つの値のどちらかを選択します。(条件 ? 真の場合の値 : 偽の場合の値)`

3.5 代入演算子

変数に値を代入します。
* =: 基本的な代入
* +=, -=, *=, /=, %=, **=, .=, x=: 算術演算や文字列演算と組み合わせた代入

“`perl
use strict;
use warnings;
use feature ‘say’;

my $count = 10;
$count += 5; # $count = $count + 5; と同じ
say “count: $count”; # 15

my $text = “Hello”;
$text .= ” World”; # $text = $text . ” World”; と同じ
say “text: $text”; # “Hello World”
“`

3.6 インクリメント/デクリメント演算子

スカラー変数の値を1だけ増減させます。
* ++: インクリメント
* --: デクリメント
これらの演算子は変数の前 (プリフィックス) または後 (ポストフィックス) に置くことができ、評価されるタイミングが異なります。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $i = 5;
say “初期値: $i”; # 5

my $j = $i++; # $j に $i の現在の値 (5) を代入した後、$i をインクリメント
say “ポストインクリメント後: i=$i, j=$j”; # i=6, j=5

my $k = ++$i; # $i をインクリメントした後、$k に $i の新しい値 (7) を代入
say “プリインクリメント後: i=$i, k=$k”; # i=7, k=7
``
デクリメント演算子
–` も同様の挙動をします。

第4章:制御構造 – 条件分岐と繰り返し

プログラムの流れを制御するために、条件分岐(特定の条件が満たされた場合にのみコードを実行)と繰り返し(特定のコードを複数回実行)の構造は不可欠です。

4.1 条件分岐 (if, elsif, else, unless)

条件が真(true)か偽(false)かに応じて、異なるコードブロックを実行します。
* if (条件式) { ... }: 条件式が真の場合にコードブロックを実行
* elsif (条件式) { ... }: 前の ifelsif の条件が全て偽で、かつこの条件式が真の場合にコードブロックを実行
* else { ... }: 前の ifelsif の条件が全て偽の場合にコードブロックを実行
* unless (条件式) { ... }: 条件式が偽の場合にコードブロックを実行 (if (!条件式) { ... } と同じ)

“`perl
use strict;
use warnings;
use feature ‘say’;

my $score = 75;

if ($score >= 90) {
say “評価: A”;
} elsif ($score >= 80) {
say “評価: B”;
} elsif ($score >= 70) {
say “評価: C”;
} else {
say “評価: D”;
}

my $is_logged_in = 0; # 偽

unless ($is_logged_in) {
say “ログインしていません。”;
}

後置if/unless修飾子

say “アクセス許可” if $score > 50;
say “アクセス拒否” unless $is_logged_in;
``
条件式は、評価結果が数値の
0、空文字列“”、未定義値undef`、または空のリスト/ハッシュであれば「偽」、それ以外であれば「真」とみなされます。

4.2 繰り返し (while, until, for, foreach)

特定のコードブロックを繰り返し実行します。

  • while (条件式) { ... }: 条件式が真の間、コードブロックを繰り返し実行します。ループに入る前に条件式が評価されます。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    my $count = 0;
    while ($count < 5) {
    say “カウント: $count”;
    $count++; # カウンタをインクリメントしないと無限ループになる
    }
    * `until (条件式) { ... }`: 条件式が偽の間、コードブロックを繰り返し実行します。これは `while (!条件式) { ... }` と同じです。perl
    use strict;
    use warnings;
    use feature ‘say’;

    my $input;
    until ($input eq “quit”) {
    print “何か入力 (‘quit’で終了): “;
    $input = ; # 標準入力から一行読み込み
    chomp $input; # 読み込んだ行末の改行コードを削除
    say “入力されたもの: $input” unless $input eq “quit”;
    }
    say “終了します。”;
    ``は標準入力から一行読み込むオペレータです。読み込んだ行には末尾に改行コード\nが含まれているため、chomp` 関数を使ってそれを取り除くのが一般的なパターンです。

  • for (初期化; 条件式; 更新式) { ... }: C言語などでおなじみの形式のループです。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    for (my $i = 0; $i < 5; $i++) {
    say “Forループ カウント: $i”;
    }
    “`

  • foreach リスト { ... } または for リスト { ... }: リストや配列の各要素に対して繰り返し処理を行います。現在の要素はループ変数に代入されます。ループ変数を指定しない場合は、デフォルト変数 $_ が使われます。
    “`perl
    use strict;
    use warnings;
    use feature ‘say’;

    my @colors = (“red”, “green”, “blue”);

    ループ変数を指定する場合

    foreach my $color (@colors) {
    say “色: $color”;
    }

    デフォルト変数 $_ を使う場合 (変数指定を省略)

    for (@colors) { # foreach の代わりに for も使える
    say “色 (デフォルト変数): $_”;
    }

    その場で作ったリストに対しても使える

    foreach my $num (1..3) {
    say “数値: $num”;
    }
    ``1..3はリスト(1, 2, 3)` を生成する範囲演算子です。

4.3 ループ制御 (last, next, redo)

ループの実行中に、特別なキーワードを使ってループの挙動を制御できます。
* last: 現在のループを完全に終了し、ループの直後の文に処理を移します。他の言語の break に相当します。
* next: 現在のループの残りの処理をスキップし、次の繰り返しに移ります。whileuntil では条件式の評価へ、for では更新式の実行へ、foreach では次の要素の処理へ移ります。他の言語の continue に相当します。
* redo: 現在のループの条件式や更新式を再評価せず、同じ繰り返しを最初からやり直します。あまり頻繁には使いません。

“`perl
use strict;
use warnings;
use feature ‘say’;

my @numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

say “偶数だけ表示 (next使用):”;
foreach my $num (@numbers) {
next unless $num % 2 == 0; # $num が偶数でない場合は次の繰り返しへ
say $num;
}

say “\n最初の5より大きい数で終了 (last使用):”;
foreach my $num (@numbers) {
last if $num > 5; # $num が5より大きくなったらループ終了
say $num;
}

redo の例 (あまり一般的な使い方ではない)

say “\nredoの例:”;
my $i = 0;
while ($i < 3) {
say “外部ループ i: $i”;
my $j = 0;
while ($j < 3) {
say ” 内部ループ j: $j”;
if ($i == 1 && $j == 1) {
say ” redo 内部ループ”;
$j++; # この行は redo されるため実行されない
redo; # 内部ループを最初からやり直す (jはそのまま)
}
$j++;
}
$i++;
}

この redo の例では、$j++ が実行されないため無限ループになります!

redo を使う際は、ループ変数の更新をどこで行うか極めて慎重に設計する必要があります。

より一般的な redo の使い方は、入力を再取得して処理をやり直す場合などです。

“`

第5章:サブルーチン(関数)

繰り返し利用する処理を一つのまとまりとして定義するのがサブルーチンです。他の言語では関数やメソッドと呼ばれるものに相当します。

5.1 サブルーチンの定義と呼び出し

サブルーチンは sub キーワードを使って定義します。
“`perl
use strict;
use warnings;
use feature ‘say’;

サブルーチンの定義

sub greet {
say “Hello!”;
}

サブルーチンの呼び出し

greet(); # () をつけて呼び出すのが一般的
&greet; # & をつけて呼び出す古い書き方もあるが、通常は()を使う
``
サブルーチンの定義は、そのサブルーチンを呼び出す場所よりも前に記述するのが一般的ですが、Perlのインタープリタはスクリプト全体を一度に読み込むため、呼び出しが定義より前でも動作します(ただし、
use strict;` を使っている場合は、定義より前に呼び出す際にプロトタイプ宣言が必要になることがあります。初心者段階では定義を先に書くと良いでしょう)。

5.2 引数

サブルーチンに値を渡すには、引数を使います。Perlでは、引数はサブルーチン内で @_ という特殊な配列変数を通してアクセスできます。@_ の各要素は、渡された引数に対応します。

“`perl
use strict;
use warnings;
use feature ‘say’;

sub say_hello {
my $name = $[0]; # @ の最初の要素にアクセス
say “Hello, $name!”;
}

say_hello(“Alice”);
say_hello(“Bob”);

sub add_numbers {
my $num1 = $[0];
my $num2 = $
[1];
my $sum = $num1 + $num2;
say “$num1 + $num2 = $sum”;
}

add_numbers(5, 3);

引数に名前を付けてアクセスする(より可読性が高い)

sub greet_person {
my ($greeting, $name) = @_; # リスト代入を使って引数に名前を付ける
say “$greeting, $name!”;
}

greet_person(“Good morning”, “Charlie”);
``my ($greeting, $name) = @_;` のようにリスト代入を使うのが、複数の引数を扱う際の慣習的で分かりやすい方法です。

5.3 戻り値

サブルーチンから呼び出し元に値を返すには、return キーワードを使います。return が省略された場合、サブルーチン内の最後の式の評価結果が戻り値となります。

“`perl
use strict;
use warnings;
use feature ‘say’;

sub multiply {
my ($x, $y) = @_;
my $result = $x * $y;
return $result; # 結果を返す
}

my $prod = multiply(4, 6);
say “積: $prod”; # 24

sub get_max {
my ($a, $b) = @_;
if ($a > $b) {
return $a;
} else {
return $b;
}
# return $a > $b ? $a : $b; # 三項演算子でも同じ
}

my $max_val = get_max(10, 20);
say “最大値: $max_val”; # 20

複数の値をリストとして返すこともできる

sub get_stats {
my @data = @;
my $count = scalar @data;
# … 平均、最大値などの計算 … (ここでは簡単化)
my $sum = 0;
$sum += $
for @data; # foreach $ (@data) { $sum += $; } と同じ
my $average = $count > 0 ? $sum / $count : 0;

return ($count, $sum, $average); # リストを返す

}

my @numbers = (10, 20, 30, 40, 50);
my ($num_count, $total_sum, $avg) = get_stats(@numbers); # リスト代入で受け取る

say “要素数: $num_count”;
say “合計: $total_sum”;
say “平均: $avg”;
“`

サブルーチンは、引数をリストとして受け取り (@_)、戻り値もリストとして返すことができます。これは、関数がリストコンテキストで呼ばれたか、スカラーコンテキストで呼ばれたかによって挙動を変えることも可能ですが、初心者には混乱しやすいため、明示的に scalar を使うなど、コンテキストを意識してコーディングするのが安全です。

5.4 スコープ (my)

my キーワードは、変数を現在のスコープ(最も内側のブロック {} 内)に閉じ込めるために使います。これはローカル変数と呼ばれ、そのブロックの外からはアクセスできません。use strict; を使っている場合、my による変数宣言が必須になります。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $global_var = “I am global”;

sub show_scope {
my $local_var = “I am local”; # サブルーチン内でのみ有効

say "Inside sub:";
say "  Global var: $global_var"; # グローバル変数にアクセス可能
say "  Local var: $local_var";   # ローカル変数にアクセス可能

if (1) { # 新しいブロック
    my $inner_var = "I am inner"; # このブロック内でのみ有効
    say "  Inside inner block:";
    say "    Inner var: $inner_var";
}
# say "  Inside inner block (outside inner_var scope): $inner_var"; # ここではエラー (inner_var はスコープ外)

}

show_scope();

say “\nOutside sub:”;
say ” Global var: $global_var”; # グローバル変数にアクセス可能

say ” Local var: $local_var”; # ここではエラー (local_var はスコープ外)

``my` を使うことで、変数の有効範囲を限定し、他の部分のコードとの名前の衝突を防ぎ、可読性や保守性を向上させることができます。これはPerlプログラミングにおいて非常に重要なプラクティスです。

第6章:ファイル入出力

Perlはファイル操作が得意な言語です。ファイルの読み込みや書き込みは、多くのスクリプトで必要となる基本的な操作です。

6.1 標準入出力

既に <STDIN>printsay を使いましたが、これらはそれぞれ標準入力、標準出力、標準エラー出力に関係します。
* <STDIN>: 標準入力から1行読み込みます。リストコンテキストではEOF (End Of File) まで全ての行をリストとして読み込みます。
* print LIST: LISTを標準出力に出力します。
* say LIST: LISTを標準出力に出力し、最後に改行を追加します。
* warn LIST: LISTを標準エラー出力に出力します。use warnings; を有効にしている場合、様々な警告も標準エラーに出力されます。
* die LIST: LISTを標準エラー出力に出力し、スクリプトを終了します。エラーが発生した場合に使われます。

“`perl
use strict;
use warnings;
use feature ‘say’;

標準入力から名前を読み込み、挨拶するプログラム

print “お名前を入力してください: “;
my $name = ;
chomp $name; # 改行を削除

say “こんにちは、” . $name . “さん!”;

エラーメッセージの例

warn “これは警告メッセージです。\n”;

die “これは致命的なエラーです。プログラムを終了します。\n”;

“`

6.2 ファイルを開く (open)

ファイルを読み書きするには、まずファイルを「開く」必要があります。open 関数は、ファイルと「ファイルハンドル」を結びつけます。ファイルハンドルは、ファイルにアクセスするための名前のようなものです。

“`perl
open my $fh, ‘<‘, ‘input.txt’ or die “Cannot open input.txt for reading: $!”;

$fh: 新しいファイルハンドル (my でローカル変数として宣言するのが推奨)

‘<‘: オープンモード。読み込みモードを指定

‘input.txt’: 開きたいファイル名

or die …: open に失敗した場合にエラーメッセージを表示してスクリプトを終了

$!: システムエラーメッセージを保持する特殊変数

open my $outfile, ‘>’, ‘output.txt’ or die “Cannot open output.txt for writing: $!”;

‘>’: オープンモード。書き込みモードを指定 (ファイルが存在すれば上書き)

open my $logfile, ‘>>’, ‘log.txt’ or die “Cannot open log.txt for appending: $!”;

‘>>’: オープンモード。追記モードを指定 (ファイルが存在すれば末尾に追加、なければ新規作成)

open my $rwfile, ‘+<‘, ‘data.txt’ or die “Cannot open data.txt for reading and writing: $!”;

‘+<‘: 読み書き両用モード (既存ファイルの先頭から)

``$!は、システムコール(この場合はopen`)が失敗した際のエラーメッセージを格納する特別な変数です。ファイルオープンに失敗した理由(例: ファイルが存在しない、権限がないなど)をユーザーに伝えるために重要です。

6.3 ファイルからの読み込み

開いたファイルハンドルを使ってファイルから内容を読み込みます。
* <ファイルハンドル>: ファイルから1行読み込みます。リストコンテキストではEOFまで全ての行をリストとして読み込みます。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $filename = ‘my_data.txt’;

ダミーファイルを作成 (実行用に)

open my $tmp_fh, ‘>’, $filename or die “Cannot create $filename: $!”;
print $tmp_fh “Line 1\n”;
print $tmp_fh “Line 2\n”;
print $tmp_fh “Line 3\n”;
close $tmp_fh;

ファイルを読み込みモードで開く

open my $fh, ‘<‘, $filename or die “Cannot open $filename for reading: $!”;

1行ずつ読み込む

while (my $line = <$fh>) {
chomp $line; # 改行コードを削除
say “Read: $line”;
}

ファイル全体を一度に読み込む (リストコンテキスト)

ファイルポインタは既にEOFにあるため、もう一度開くか seek する必要がある

close $fh; # 一度閉じる

open my $fh_all, ‘<‘, $filename or die “Cannot open $filename again: $!”;
my @lines = <$fh_all>; # ファイル全体をリストとして読み込み
close $fh_all;

say “\n— ファイル全体読み込み —“;
foreach my $line (@lines) {
chomp $line;
say “Read (all): $line”;
}

ファイルを閉じる

unlink $filename; # ダミーファイルを削除
“`

6.4 ファイルへの書き込み

開いたファイルハンドルを使ってファイルに内容を書き込みます。
* print ファイルハンドル LIST: 指定したファイルハンドルにLISTを出力します。
* say ファイルハンドル LIST: 指定したファイルハンドルにLISTを出力し、改行を追加します。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $output_filename = ‘my_output.txt’;

ファイルを書き込みモードで開く (存在すれば上書きされる)

open my $outfile, ‘>’, $output_filename or die “Cannot open $output_filename for writing: $!”;

ファイルに書き込む

print $outfile “This is the first line.\n”;
say $outfile “This is the second line.”;
print $outfile “This is the third line.”; # 末尾に改行なし

ファイルを閉じる

close $outfile;

say “$output_filename に書き込みました。内容を確認してください。”;

ファイルを追記モードで開く

open my $appendfile, ‘>>’, $output_filename or die “Cannot open $output_filename for appending: $!”;

ファイルの末尾に追記

say $appendfile “This is an appended line.”;

ファイルを閉じる

close $appendfile;

say “$output_filename に追記しました。内容を確認してください。”;

ファイルを削除

unlink $output_filename;

“`

6.5 ファイルを閉じる (close)

ファイルを使い終わったら、close 関数を使ってファイルを閉じるべきです。これにより、バッファリングされたデータがファイルに書き込まれたり、システムリソースが解放されたりします。スクリプトの終了時に開いているファイルは自動的に閉じられますが、明示的に閉じるのが良い習慣です。

第7章:正規表現 – Perlの強力な武器

正規表現(Regular Expression、略称:regex または regexp)は、文字列の中から特定のパターンに一致する部分を検索したり、置換したりするための強力なツールです。Perlは正規表現の機能を非常に高度かつ効率的に実装しており、Perlの大きな強みの一つとされています。

7.1 正規表現の基本

Perlで正規表現を使う主な演算子は以下の通りです。
* マッチング演算子: =~ m/パターン/ または単に /パターン/ (デフォルト変数 $_ に対してマッチング)
* 置換演算子: =~ s/パターン/置換文字列/
* 変換演算子: =~ tr/検索文字リスト/置換文字リスト/ または y/検索文字リスト/置換文字リスト/ (文字の変換)

“`perl
use strict;
use warnings;
use feature ‘say’;

my $text = “Hello, world! Perl is powerful.”;

マッチング

if ($text =~ m/Perl/) { # $text に “Perl” が含まれているか?
say “‘Perl’ が見つかりました。”;
}

if ($text =~ /world/) { # $ がデフォルトの場合、=~ m/ は省略できる
# say $
; # このifブロック内では $text が $_ にコピーされるわけではないので注意
say “‘world’ が見つかりました。”;
}

置換

my $modified_text = $text;
$modified_text =~ s/world/Perl/; # 最初に見つかった “world” を “Perl” に置換
say “置換後: $modified_text”; # Hello, Perl! Perl is powerful.

my $another_text = “Perl and perl and PERL”;
$another_text =~ s/perl/regex/; # デフォルトでは最初の一つだけ置換
say “最初の置換: $another_text”; # Perl and regex and PERL

$another_text = “Perl and perl and PERL”;
$another_text =~ s/perl/regex/gi; # オプション: g (全体置換), i (大文字小文字を区別しない)
say “全体+無視置換: $another_text”; # regex and regex and regex
“`

7.2 メタ文字とエスケープ

正規表現パターンの中で特別な意味を持つ文字を「メタ文字」と呼びます。
.: 任意の一文字 (改行を除く)
^: 行の先頭
$: 行の末尾
*: 直前の文字が0回以上繰り返す
+: 直前の文字が1回以上繰り返す
?: 直前の文字が0回または1回出現する
|: OR (選択)
(): グループ化、キャプチャ
[]: 文字クラス ([]内のいずれか一文字に一致)
{}: 量指定子 (直前の文字の出現回数を指定)
\: 次に来るメタ文字をエスケープ(文字そのものとして扱う)

“`perl
use strict;
use warnings;
use feature ‘say’;

my $data = “abc 123.xyz\n456-789\nend.”;

say “ドット (.) の例:”;
if ($data =~ /123.xyz/) { say ” ‘123.xyz’ にマッチ”; } # ドットは任意の文字にマッチ

say “\n^ と $ の例:”;
if ($data =~ /^abc/) { say ” 行頭に ‘abc’ にマッチ”; }
if ($data =~ /end.$/) { say ” 行末に ‘end.’ にマッチ (ドットはエスケープ)”; }

say “\n と + と ? の例:”;
if ($data =~ /ab
c/) { say ” ‘ac’ や ‘abc’, ‘abbc’ などにマッチ”; } # * は b が0回以上
if ($data =~ /ab+c/) { say ” ‘abc’ や ‘abbc’ などにマッチ”; } # + は b が1回以上
if ($data =~ /ab?c/) { say ” ‘ac’ や ‘abc’ にマッチ”; } # ? は b が0回か1回

say “\n| の例:”;
if ($data =~ /123|456/) { say ” ‘123’ または ‘456’ にマッチ”; }

say “\n() グループ化の例:”;
if ($data =~ /(abc).*(xyz)/s) { # s オプションで . が改行にもマッチするように
say ” ‘abc’ と ‘xyz’ が見つかりました”;
}

say “\n[] 文字クラスの例:”;
if ($data =~ /[0-9]+/) { say ” 数字列 ([0-9]は0から9のいずれかの文字) にマッチ”; } # + は1回以上
if ($data =~ /[aeiou]+/) { say ” 母音 ([aeiou]はいずれかの母音) にマッチ”; }
if ($data =~ /[^aeiou]+/) { say ” 母音以外の文字 ([^…]は否定) にマッチ”; } # ^ が [] 内の先頭にある場合は否定

say “\n{} 量指定子の例:”;
if ($data =~ /\d{3}/) { say ” 連続する数字3桁 (\dは数字) にマッチ”; }
if ($data =~ /\d{3,}/) { say ” 連続する数字3桁以上 にマッチ”; }
if ($data =~ /\d{3,5}/) { say ” 連続する数字3桁から5桁 にマッチ”; }
“`

7.3 文字クラスショートカット

よく使う文字クラスにはショートカットが用意されています。
\d: 数字 ([0-9] と同じ)
\D: 数字以外 ([^0-9] と同じ)
\w: 単語構成文字 (英数字とアンダースコア [a-zA-Z0-9_] と同じ)
\W: 単語構成文字以外 ([^a-zA-Z0-9_] と同じ)
\s: 空白文字 (スペース、タブ、改行など [\s] と同じ)
\S: 空白文字以外 ([^\s] と同じ)

“`perl
use strict;
use warnings;
use feature ‘say’;

my $text = “Date: 2023/10/27 Time: 14:30”;

\d を使って日付のパターンにマッチ

if ($text =~ /\d{4}\/\d{2}\/\d{2}/) {
say “日付パターンが見つかりました。”;
}

\w+ を使って単語にマッチ

my @words = $text =~ /\w+/g; # g オプションで全てのマッチをリストで取得
say “単語リスト: @words”;

\s+ を使って連続する空白にマッチ

my @parts = split(/\s+/, $text); # 1つ以上の空白で文字列を分割
say “分割された部分: @parts”;
“`

7.4 キャプチャ (()) とキャプチャ変数 ($1, $2, …)

正規表現のパターン内で括弧 () を使うと、マッチした部分文字列をキャプチャ(取得)できます。キャプチャされた文字列は $1, $2, $3, … という特殊な変数に格納されます。

“`perl
use strict;
use warnings;
use feature ‘say’;

my $log_line = “ERROR: Invalid input user=admin at line 123”;

if ($log_line =~ /ERROR: (.) user=(.) at line (\d+)/) {
my $message = $1; # 最初の () の内容
my $username = $2; # 2番目の () の内容
my $line_num = $3; # 3番目の () の内容 (\d+ にマッチした部分)

say "エラーメッセージ: $message";
say "ユーザー名: $username";
say "行番号: $line_num";

}

s/// 置換演算子の中でもキャプチャ変数を利用できる

my $url = “http://example.com/path/to/file.html”;
$url =~ s/^http:\/\/(.?)\/(.)$/$2 on $1/; # http:// ドメイン / パス/ファイル名 を パス/ファイル名 on ドメイン に置換
say “URL変換後: $url”; # path/to/file.html on example.com
“`

7.5 正規表現オプション

マッチング /.../ や置換 s/.../.../ 演算子の最後に付けることで、挙動を変更できます。
i: 大文字小文字を区別しない (case-insensitive)
g: グローバルマッチ (対象文字列中の全てのマッチを検索・置換)
s: ドット . が改行 \n にもマッチするようにする (デフォルトではマッチしない)
m: ^$ が文字列全体の先頭/末尾だけでなく、行の先頭/末尾 (改行の直後/直前) にもマッチするようにする (multi-line)
x: パターン中の空白やコメントを無視し、読みやすく記述できるようにする

“`perl
use strict;
use warnings;
use feature ‘say’;

my $text = “Apple, BANANA, Cherry”;

i オプション

if ($text =~ /apple/i) { say “‘apple’ (iオプション) が見つかりました”; }

g オプション

my @matches = $text =~ /[A-Za-z]+/g; # 全ての単語を抽出
say “抽出された単語: @matches”; # Apple BANANA Cherry

s オプション

my $multi_line_text = “Line 1\nLine 2”;
if ($multi_line_text =~ /Line.Line/) { say “. は改行にマッチしない (デフォルト)”; }
if ($multi_line_text =~ /Line.Line/s) { say “. は改行にマッチする (sオプション)”; }

m オプション

$multi_line_text = “Line 1\nLine 2\n”;
if ($multi_line_text =~ /^Line 2$/) { say “^$ は文字列全体に対してマッチ”; } # マッチしない (Line 1 から始まっている)
if ($multi_line_text =~ /^Line 2$/m) { say “^$ は行に対してマッチ (mオプション)”; } # マッチする (Line 2 の行に対して)

x オプション

my $long_pattern = qr{ # qr{} は正規表現をコンパイルし、あとで使えるようにする演算子
^(\d{4}) # 4桁の数字 (年)
\/ # スラッシュ
(\d{2}) # 2桁の数字 (月)
\/ # スラッシュ
(\d{2}) # 2桁の数字 (日)
$ # 行末
}x; # x オプションを有効にする

my $date_str = “2023/10/27”;
if ($date_str =~ $long_pattern) {
say “日付パターンにマッチしました (xオプション使用)”;
say “年: $1, 月: $2, 日: $3”;
}
``
正規表現はPerlの強力な機能ですが、複雑になりがちです。はじめは簡単なパターンから始め、徐々に慣れていくことが重要です。
perldoc perlretut` コマンドで正規表現のチュートリアル(英語)を読むことも参考になります。

第8章:モジュール

Perlの標準機能だけでは不十分な場合や、他の人が書いた便利なコードを利用したい場合があります。そのようなときに使うのがモジュールです。Perlのモジュールは、関連する機能を持つサブルーチンや変数、オブジェクト指向的な機能などをまとめたファイルです。

8.1 モジュールの利用 (use)

他のモジュールを利用するには、スクリプトの冒頭で use キーワードを使います。
“`perl
use strict;
use warnings;
use feature ‘say’;

use File::Basename; # File::Basename モジュールを利用可能にする

my $filepath = “/home/user/documents/report.txt”;

my $basename = basename($filepath); # モジュール内の関数を呼び出す
my $dirname = dirname($filepath);
my ($name, $path, $suffix) = fileparse($filepath); # リストで複数の値を返す関数

say “元のパス: $filepath”;
say “ファイル名: $basename”; # report.txt
say “ディレクトリ名: $dirname”; # /home/user/documents
say “ファイル名とパスと拡張子: $name, $path, $suffix”; # report, /home/user/documents/, .txt
``use ModuleName;` は、指定したモジュールを読み込み、そのモジュールが提供する機能(変数、サブルーチン、オブジェクトなど)を現在のスクリプトで使えるようにします。多くのモジュールは、特定の機能を提供する関数をエクスポート(利用可能に)します。

8.2 CPAN (Comprehensive Perl Archive Network)

PerlにはCPANという世界最大級のソフトウェアアーカイブがあります。ここには、ファイル操作、ネットワーク、データベース、Web開発、GUI、データ構造、アルゴリズムなど、あらゆる分野のモジュールが膨大に集められています。CPANのモジュールを利用することで、ゼロからコードを書く手間を省き、効率的に開発を進めることができます。

CPANモジュールをインストールするには、通常はコマンドラインツールを使います。
* cpan: 標準のCPANクライアント。対話的または非対話的にモジュールをインストールできます。
bash
cpan # 対話モードに入る (初回は設定が必要)
install Module::Name # インストールしたいモジュール名
quit # 終了

または非対話的に: cpan -i Module::Name
* cpanm (cpanminus): 軽量で使いやすい代替クライアント。多くの場合こちらの方が簡単です。
bash
cpanm Module::Name

cpanm 自体は cpan App::cpanminus でインストールできます。

例:JSONデータを扱うための JSON::PP モジュールをインストール・利用する
bash
cpanm JSON::PP

“`perl
use strict;
use warnings;
use feature ‘say’;

use JSON::PP; # JSON::PP モジュールを利用

my $data = {
name => ‘Alice’,
age => 30,
city => ‘Tokyo’
};

PerlのハッシュをJSON文字列にエンコード

my $json_string = encode_json($data);
say “JSONエンコード結果: $json_string”; # {“name”:”Alice”,”age”:30,”city”:”Tokyo”} (順序は不定)

JSON文字列をPerlのデータ構造にデコード

my $json_data_str = ‘{“product”:”Laptop”,”price”:1200}’;
my $decoded_data = decode_json($json_data_str);

say “JSONデコード結果:”;
say ” 製品: ” . $decoded_data->{‘product’};
say ” 価格: ” . $decoded_data->{‘price’};
``
CPANモジュールは、Perlプログラミングの可能性を大きく広げます。何かやりたいことがあれば、まずCPANで関連するモジュールがないか探してみるのが良いでしょう。
metacpan.org` というウェブサイトでモジュールを検索できます。

第9章:さらにステップアップするために

このガイドでPerlの基本的な文法、変数、制御構造、サブルーチン、ファイル入出力、正規表現、モジュールの使い方を学びました。しかし、Perlにはさらに多くの機能や概念があります。

  • リファレンス: 配列やハッシュなどの複雑なデータ構造をサブルーチンに渡したり、入れ子になったデータ構造を作成したりするために使われる「参照」です。例えば、my $array_ref = \@my_array; のように書きます。リストやハッシュの要素として他のリストやハッシュを入れたい場合に必須となります。
  • オブジェクト指向プログラミング (OOP): Perlはオブジェクト指向プログラミングもサポートしています。クラスの定義、オブジェクトの生成、メソッドの呼び出しなどを行うことができます。
  • デバッグ: perl -d your_script.pl のようにコマンドを実行することで、Perlのデバッガを使ってスクリプトの実行をステップ実行したり、変数の値を調べたりすることができます。
  • テスト: モジュール開発や重要なスクリプトを書く際には、テストコードを書くことが推奨されます。PerlにはTest::Moreなどの強力なテストフレームワークがあります。
  • Perlの特殊変数: $!, $_, @_ の他にも、Perlには多くの特殊変数があります(例: $? コマンドの終了ステータス、$. 最後に読み込んだファイルの行番号など)。これらを使いこなすと便利な場面が多いですが、使いすぎるとコードが読みにくくなることもあります。
  • ワンライナー: コマンドラインで短いPerlコードを実行するための便利な記法です。特にテキスト処理で強力です (perl -e '...', perl -n '...', perl -p '...')。
  • コミュニティとドキュメント: Perlには活発なコミュニティと豊富なドキュメントがあります。perldoc commandperldoc function_nameperldoc perlfaqperldoc perlretut など、様々な情報をコマンドラインから参照できます。

第10章:まとめと次のステップ

この入門ガイドでは、Perlプログラミングの基礎を幅広くカバーしました。Perlがテキスト処理やシステム管理の分野で今もなお強力なツールであり続けている理由、そしてその基本的な使い方を理解できたことと思います。

学んだことの要点:

  • Perlの歴史、哲学、得意分野
  • Perl環境のセットアップとスクリプトの実行
  • use strict;use warnings; の重要性
  • スカラー ($), 配列 (@), ハッシュ (%) の基本的な使い方
  • 様々な演算子(算術、文字列、比較、論理、代入)
  • 条件分岐 (if, unless) と繰り返し (while, until, for, foreach)
  • サブルーチンの定義、引数、戻り値、スコープ (my)
  • ファイル入出力 (open, close, <FH>, print FH, say FH, die)
  • 正規表現の基本(マッチング m//, 置換 s///, メタ文字、量指定子、文字クラス、キャプチャ、オプション)
  • モジュールの利用 (use) とCPANの活用方法

Perlは非常に柔軟な言語であり、一つの問題を解決するために多様な方法が存在します。この柔軟性は強力であると同時に、初心者には「最適な書き方」が分かりにくいと感じるかもしれません。しかし、まずはこのガイドで紹介した基本的な書き方をしっかりと身につけ、シンプルなコードから書き始めてみてください。

次のステップ:

  1. 自分でコードを書いてみる: このガイドのコード例を写経するだけでなく、自分で簡単な問題(例: ファイルから特定の行を抜き出す、文字列を整形する、簡単な計算を行うスクリプトなど)を設定して、ゼロからPerlコードを書いてみましょう。
  2. エラーや警告を読み解く練習: use strict; use warnings; を有効にしてコードを書き、出てくるエラーメッセージや警告メッセージの意味を理解する練習をしましょう。これはデバッグ能力を高める上で非常に重要です。
  3. Perlの公式ドキュメントを読む: コマンドラインから perldoc コマンドを使って、興味を持った関数や概念のドキュメントを読んでみましょう。最初は難しく感じるかもしれませんが、慣れると強力なリファレンスになります。
  4. CPANモジュールを使ってみる: 興味のある分野(例えば、ネットワーク通信、Webスクレイピング、データベース操作など)のCPANモジュールを探して、インストールし、ドキュメントを見ながら使ってみましょう。
  5. Perlの学習リソースを探す: オンラインのチュートリアル、書籍、コミュニティサイトなど、さらに学習を深めるためのリソースはたくさんあります。

Perlは学ぶべきことが多く、その独特な文法に最初は戸惑うかもしれません。しかし、テキスト処理やシステム管理といった領域においては、今も非常に強力で効率的な言語です。このガイドが、あなたのPerlプログラミング学習の良いスタート地点となることを願っています。

Happy Perl hacking!


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール