あのぞんブログ

各言語特有っぽい構文: Perl

2025-12-05

この記事は

5 日目の記事です。

個人的な好みを交えて紹介します。

二分探索のサンプルコード

言語の特徴をあえて使い実装している。

# Perl - 正規表現 + 特殊変数 + wantarray
sub binary_search {
    my ($arr, $target) = @_;
    my ($left, $right) = (0, $#$arr);

    while ($left <= $right) {
        my $mid = int(($left + $right) / 2);
        given ($arr->[$mid] <=> $target) {
            when (0)  { return $mid }
            when (-1) { $left = $mid + 1 }
            when (1)  { $right = $mid - 1 }
        }
    }
    return -1;
}

my @arr = (1, 3, 5, 7, 9);
print binary_search(\@arr, 5);  # 2

ピックアップ構文

特殊変数

暗黙的に値が設定される変数。$_$1 など多数存在する。

# 配列の最後のインデックス
$#arr        # @arr の最後のインデックス
$#$arr_ref   # リファレンス経由

# デフォルト変数 $_
@doubled = map { $_ * 2 } @arr;
print for @arr;  # 各要素を出力

# 正規表現マッチ結果
if ($str =~ /(\d+)-(\d+)/) {
    print "$1 to $2";  # $1, $2 はキャプチャグループ
}

bash のような雰囲気が出ている。

リファレンスとデリファレンス

C のポインタに似た参照機構。複雑なデータ構造を扱うのに必須。

# リファレンス作成
my $arr_ref = \@arr;
my $hash_ref = \%hash;

# デリファレンス
@{$arr_ref}      # 配列として
$arr_ref->[$i]   # アロー記法

# 無名配列/ハッシュ
my $arr = [1, 2, 3];
my $hash = { key => 'value' };

宇宙船演算子 <=>

比較結果を -1, 0, 1 で返す。ソート関数との相性が良い。

# 数値比較: -1, 0, 1 を返す
5 <=> 3   # 1
3 <=> 5   # -1

# 文字列版
"abc" cmp "def"  # -1

# ソートで活用
@sorted = sort { $a <=> $b } @arr;  # 数値昇順
@sorted = sort { $b <=> $a } @arr;  # 数値降順

実装する言語が増えているイメージがある。

given-when (switch 文)

パターンマッチ可能な switch 文。正規表現や配列もマッチできる。

use feature 'switch';

given ($value) {
    when (1)     { say "one" }
    when ([2,3]) { say "two or three" }
    when (/^\d+$/) { say "number" }
    default      { say "other" }
}

文脈依存の戻り値 wantarray

呼び出し元がリスト/スカラー/void のどれを期待しているか検知できる。

sub get_data {
    my @data = (1, 2, 3);
    if (wantarray) {
        return @data
     } elsif (defined wantarray) {
        return scalar @data
     } else {
        warn "No return value expected";
     }
}

my @arr = get_data();  # (1, 2, 3)
my $count = get_data();  # 3
get_data(); # 警告

とても面白い。呼び出し元のコンテキストを暗黙的に検知できる。

引数(に命名する書き方がなかった)

Perl 5.20 からよくある引数の書き方ができるようになっている。

# 以前
sub add {
    my ($x, $y) = @_;
}

# 以降
sub add ($x, $y) {
}

© 2026 あのぞんびより