Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

タグ:perl

  • 行入力演算子:<>
#!/usr/bin/env perl
use v5.12;
use warnings;

while (defined(my $line = <STDIN>)) {
    say "I saw $line";
}

# defined($line = <STDIN>) の省略形
while (<STDIN>) {
    say "I saw $_";
}

# <STDIN> で1行ずつ読み込むのは、whileの場合だけ。

# foreachだと、全ての行を一度に読み込んで$_ に突っ込む
foreach (<STDIN>) {
    say "I saw $_";
}
ダイヤモンド演算子<>:ユーザーが指定した場所から入力を読み取り
#!/usr/bin/env perl
use v5.12;
use warnings;

# このプログラムを ./diamond.pl hoge.txt というコマンドで起動すると、
# hoge.txtの内容を読み取って出力する
while (<>) {
    chomp;
    say "It was $_ that I saw!";
}
autodie:
#!/usr/bin/env perl
use v5.12;
use autodie;

open HOGE, '>>', 'hoge'; # openが失敗すると自動的にdie
変数名の区切り:
#!/usr/bin/env perl
use v5.12;
use warnings;

$str = "12345";
$width = 10;
printf("%$widths", $str); # $widths が未定義だという警告が出る
printf("%${width}s", $str); # ${変数名} と書けば、変数名の区切りを明示できる

  • Perlでは、ユーザーが定義した関数のことをサブルーチン(subroutine)と呼ぶ
  • サブルーチンの名前には、頭にアンパーサンド(&)をつける(省略してもコードの意味が変わらない場合には、省略できる)
  • サブルーチンはファイル内のどこで定義してもよい(プロトタイプに関する例外はある)
  • サブルーチンのスコープは原則としてグローバル
  • 同じ名前のサブルーチン定義が2個あると、後ろにあるものが前のものを上書きする(use warningsをつければ検出可能)
  • use strict をつけると未定義変数の使用等に警告が出る。
  • プラグマで最低限必要なバージョンとして5.12以降を指定すると、暗黙のうちにstrictプラグマも有効になる
サブルーチンの中で最後に行われた計算の結果が、自動的に戻り値になる:
#!/usr/bin/env perl
use v5.12;
use warnings;

sub two {
    1 + 1;
}

say &two; # 2
サブルーチンに与えた引数は、$_[0], $_[1], ... といった変数に格納される(配列@_からも引数を取り出せる):
#!/usr/bin/env perl
use v5.12;
use warnings;

sub max {
    if ($_[0] > $_[1]) {
        $_[0];
    } else {
        $_[1];
    }
}

say max(1, 2); # 2
say max(1); # Use of uninitialized value in numeric gt (>)
say max(1, 2, 3); # 2(警告無し)
変数名の前にmyをつけることで、レキシカル変数を作れる。レキシカル変数のスコープはブロック内のみ。
#!/usr/bin/env perl
use v5.12;
use warnings;

sub max {
    my ($m, $n) = @_;
    if ($m > $n) { $m } else { $n }
}

say max(1, 2); # 2
可変長引数:
#!/usr/bin/env perl
use v5.12;
use warnings;

sub max {
    my ($max_so_far) = shift @_; # 最初の引数を暫定版の最大値とする
    foreach (@_) { # 残りの引数を暫定版の最大値と比較する
        if ($_ > $max_so_far) {
            $max_so_far = $_;
        }
    }
    $max_so_far;
}

say &max(2, 7, 5, -1); # 7
stateで永続的なプレイベート変数を定義する(PHPでいうstatic):
#!/usr/bin/env perl
use v5.12;
use warnings;

sub inc {
    state $n = 0;
    $n += 1;
    say $n;
}

inc; # 1
inc; # 2
inc; # 3
配列・ハッシュをstate変数として使う場合は、リストコンテキストでの初期化ができない
state @array = qw(a b c); # エラー

  • リスト(list):スカラーの集合に順序を付けて並べたもの
  • 配列(array):リストを格納する変数

PHPの世界では何でもかんでも「配列(array)」だけど、Perlの世界では中身(リスト)と容れ物(配列)を区別する。たぶんPHPの方が異端。

配列とスカラー変数の名前空間は衝突しない:
#!/usr/bin/env perl
use v5.12;
use warnings;

my $var;
my @var;

$var = 'hoge';
$var[0] = 'fuga';

print $var, "\n"; # hoge
print $var[0], "\n"; # fuga
範囲演算子(PHPだとrange()):
#!/usr/bin/env perl
use v5.12;
use warnings;

my @range;

@range = (1..10); # @rangeに1から10までを格納したリストが入る

foreach (@range) {
    say; # 1から10まで改行しながら出力
}
qwショートカット:qwとデリミタで囲まれ、空白文字列で区切られた文字列は、それぞれシングルクォートで囲まれた文字列とみなされる
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array1;
my @array2;
my @array3;

@array1 = ("hoge", "fuga", "piyo!");
@array2 = qw(hoge fuga piyo!); # 処理の内容は上と同じ
@array3 = qw! hoge fuga piyo\! !; # デリミタは任意の記号文字を使える。\でエスケープ。

foreach (@array2) {
    say; # hoge fuga piyo!
}
リスト代入:リスト値を変数に代入(PHPだとlist()
my ($hoge, $fuga, $piyo) = ('hoge', 'fuga', 'piyo');
pop:末尾から引っこ抜く
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array = 1..9;
my $pop = pop @array; # 9が取り除かれ、$popに代入される
say $pop; # 9

pop @array; # 8が取り除かれる
foreach (@array) {
    say; # 1..7
}
push:末尾に突っ込む
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array;
push @array, 0;
push @array, "hoge";

foreach (@array) {
    say; # 0, hoge
}
shift/unshift:先頭から引き抜く/先頭に突っ込む
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array = qw(hoge fuga);
my $hoge = shift @array; # "hoge"が引っこ抜かれて$hogeに代入される
say $hoge; # hoge

shift @array; # "fuga"が引っこ抜かれて捨てられる
unshift @array, "piyo"; # "piyo"をリストに追加

my @array2 = qw(foo bar);
unshift @array, @array2; # 2つの配列を合体

foreach (@array) {
    say; # foo, bar, piyo
}
なお、配列中の任意の位置から値を取り除いたり、任意の位置に値を挿入する方法として、spliceがある。ただ、spliceは用例が長くなるので省略。

変数展開:配列はダブルクォートで囲まれると変数展開される
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array = qw(fuga piyo);
say @array; # fugapiyo(値の間に半角スペースは入らない)
say "hoge @array"; # hoge fuga piyo (ダブルクォートで囲むと、半角スペースが入る)
say "test@example.com"; # @example という変数を展開しようとしてエラーが出る
say 'test@example.cpm'; # シングルクォートで囲えば変数展開されない
デフォルト変数 $_:Perlは、変数名を指定しない場合、$_をデフォルト変数として使うことが多い
#!/usr/bin/env perl
use v5.12;
use warnings;

my @array = 0..2;

foreach my $val (@array) { # 制御変数 $valを定義
    $val += 1; # 制御変数の値を変更すると、元の配列にも影響が及ぶ
}

say "@array"; # 1 2 3

foreach (@array) {
    say $_; # 制御変数を指定しないと、$_がデフォルト変数として設定される
    say; # printやsayは、引数を指定しない場合、$_の値を出力する
}

  • Perlは整数と小数を区別しない
  • ダブルクォート文字列の内部では変数が展開される(PHPと同じ)
  • 文字列の連結は .(ドット)演算子を使う(PHPと同じ)
  • スカラー値を格納した変数は、頭に $(ドル)記号をつける(PHPはあらゆる変数の頭に$がつくけど、Perlはスカラー値のみ)
  • 数値の比較: ==(等しい)  !=(等しくない)
  • 文字列の比較: eq(等しい) と ne(等しくない)
  • PerlにBoolean型は無い。falseと評価されるのは、数値の0、空文字列、数値として評価して0になる値(文字列の'0'、空配列など)
  • <STDIN>で標準入力を受け付ける



初めてのPerl 第6版
Randal L. Schwartz
オライリージャパン
2012-07-25

『初めてのPerl』のサンプルコード:http://www.learning-perl.com/

「Perlを設計する際に、Larryはたくさんのトレードオフを考慮しなければなりませんでした。学ぶことが難しくなる代わりに、何かが簡単にできるようになるという機会があれば、ほとんどの場合、簡単にできることを優先させました。なぜなら、Perlを学ぶのは1回限りのことですが、何回も何回も繰り返し使うからです。」 - p.6-7

「Perlは、少なくとも毎日20分間はプログラムを(ほとんどPerlで)書く人向けの言語です」 - p.7

「プログラムの1つのセクションが、1画面に収まらなくなった途端に急にバグが増えます」 - p.8
#!/usr/bin/perl
@lines = `perldoc -u -f atan2`;
foreach (@lines) {
  s/\w<[^>]+>/\U$1/g;
  print;
}
初めてのPerl 第6版
Randal L. Schwartz
オライリージャパン
2012-07-25

このページのトップヘ