Perl 7

驚きのニュースが飛び込んできた。Perl が約25年ぶりのメジャーバージョンアップだと。

どのくらい驚いたかって、Perl の記事がほとんどないこのブログにも書いちゃうくらい驚いた。

とりあえず記録として残しておく。

Perlの配列をn個ずつの配列に分割する

splice して push する。破壊的なので注意。

use strict;
use warnings;

sub chunk {
    my $ary = shift @_;
    my $n = shift @_;
    my $result = [];

    while (@$ary) {
        my @s = splice(@$ary, 0, $n);
        push(@$result, \@s);
    }

    return $result;
}

my $array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

print("array:", @$array, "\n");

my $chunked = chunk($array, 3);
foreach my $c (@$chunked) {
    print("chunk:", @$c);
    print("\n");
}

print("array:", @$array, "\n");
^o^ > perl chunk.pl
array:0123456789
chunk:012
chunk:345
chunk:678
chunk:9
array:

Perlでランダムな文字列を得る

ググってみると String::Random モジュールを使うといいらしいんだけど、うまくインストールできなかったので(原因不明)、もっとベタな方法でやることにした。

use strict;
use warnings;

sub randstr {
    my $length = shift(@_);

    my @chars;
    push(@chars, ('A'..'Z'));
    push(@chars, ('a'..'z'));
    push(@chars, ('0'..'9'));

    my $rand_str = '';

    for (my $i = 1; $i <= $length; $i++) {
        $rand_str .= $chars[int(rand($#chars+1))];
    }

    return $rand_str;
}

my $length = shift(@ARGV);
print randstr($length);

$#chars という表現は、配列 @chars の最後のインデックスを取得している。こんな書き方があるとは初めて知った。

実行結果:

^o^ > random_string.pl 20
LxN8r4RSM8rdZ4iQdp3r

Perl でファイルから行を読み込む

Perl はたまにしか使わないからいつまでたっても覚えない。のでメモ。

ファイルから1行だけ読み込むには:

use strict;
use warnings;

my $file = shift;
open(my $fh, '<', $file) or die "$file: $!";
my $line = <$fh>;

print $line;

実行結果:

^o^ > type sample.txt
sun
mon
tue
wed
thu
fri
sat

^o^ > perl read_line.pl sample.txt
sun

スカラー変数じゃなくて配列変数に代入すると、ファイル全体が1行ずつの配列になる。

use strict;
use warnings;

my $file = shift;
open(my $fh, '<', $file) or die "$file: $!";
my @lines = <$fh>;

foreach my $line (@lines) {
    print $line;
}

実行結果:

^o^ > perl read_lines.pl sample.txt
sun
mon
tue
wed
thu
fri
sat

1行ずつ読み込みながら処理するには、while ループと一緒に使う:

use strict;
use warnings;

my $file = shift;
open(my $fh, '<', $file) or die "$file: $!";

while (my $line = <$fh>) {
    print uc($line);
}

実行結果:

^o^ > perl read_lines_loop.pl sample.txt
SUN
MON
TUE
WED
THU
FRI
SAT

Perlでファイル名の拡張子を取得する

File::Basename モジュールの fileparse 関数を使う。

use strict;
use warnings;

use File::Basename qw/ fileparse /;

my $file = shift @ARGV;

(my $base, my $dir, my $ext) = fileparse($file, qr/\..+$/);

print "dir: $dir\n";
print "base: $base\n";
print "ext: $ext\n";

fileparse の返り値の順番が、ファイル名、ディレクトリ名、拡張子であることに注意。ふつうディレクトリ名が最初だと思うよなぁ。

実行結果:

^o^ > perl fileparse.pl sample.txt
dir:  .\
base: sample
ext:  .txt