$ENV{} から削除を行な
うと、実際に環境変数を変更します。DBM ファイルに tie された配列か
らの削除は、その DBM ファイルからエントリを削除します。(しかし、
tie されたハッシュからの削除が、値を返すとは限りません。)
以下は、連想配列のすべての value を削除します:
foreach $key (keys %ARRAY) {
delete $ARRAY{$key};
}
(ただし、undef() コマンドを使った方が速いでしょう。)最終的な操作
がハッシュの key による検索である限りは、$var{expr} には任意の複雑な式を
置くことができます:
delete $ref->[$x][$y]{$key};
each() を呼び出すと、再び繰り返しを始めます。反復子は、配列の要素
をすべて読むことによってのみリセットすることができます。繰り返しを行なっ
ている間に、配列に要素を追加してはなりません。連想配列ごとに反復子が 1
つあり、プログラム中のすべての each() 関数、keys() 関数、
values() 関数で共用されます。以下のプログラムは、順番が異なるもの
の、printenv(1) プログラムのように環境変数を表示します:
while (($key,$value) = each %ENV) {
print "$key=$value\n";
}
keys() や values() も参照してください。
print "Exists\n" if exists $array{$key};
print "Defined\n" if defined $array{$key};
print "True\n" if $array{$key};
ハッシュ要素は、定義されているときにのみ真となり、存在しているときにのみ 定義されますが、逆は必ずしも真ではありません。
最終的な操作がハッシュの key による検索である限りは、$var{expr} には任意 の複雑な式を置くことができます:
if (exists $ref->[$x][$y]{$key}) { ... }
@foo = grep(!/^#/, @bar); # コメント行の除去
は
@foo = grep {!/^#/} @bar; # コメント行の除去
は、同じことをします。
$_ は、list の値へのリファレンスですので、配列の要素を変更するため に使うことができます。これは、便利でサポートされていますが、list が名前の付いた配列でないと、悲惨な結果になります。
$_ = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
このSee section 組み込み関数,の split の項も参照してください。
values() 関数や
each() 関数で返されるものと同じ順序です。環境変数を表示する別の例
です:
@keys = keys %ENV;
@values = values %ENV;
while ($#keys >= 0) {
print pop(@keys), '=', pop(@values), "\n";
}
key をソートしてもいいでしょう:
foreach $key (sort(keys %ENV)) {
print $key, '=', $ENV{$key}, "\n";
}
@chars = map(chr, @nums);
は、数のリストを対応する文字に変換します。また、
%hash = map {&key($_), $_} @array;
は、
%hash = ();
foreach $_ (@array) {
$hash{&key($_)} = $_;
}
をちょっと変わった書き方で書いたものです。
$tmp = $ARRAY[$#ARRAY--];
と同じ効果があります。指定された配列に要素がなければ、未定義値が返されま す。
for $value (LIST) {
$ARRAY[++$#ARRAY] = $value;
}
とするのと同じ効果がありますが、より効率的です。変更後の配列の要素数を返 します。
shift し、サブルーティンでは、@_ 配列を shift します。(こ
れは、文面上で決まります。) unshift()、push()、
pop() も参照してください。shift() と unshift() は、
push() と pop() が配列の右端で行なうことを、左端で行ないま
す。
<=> 演算子や cmp 演算子が、たいへん便利です。)
subname は、スカラ変数でもよく、その場合には、その値が使用するサブ
ルーティンの名前と解釈されます。subname の代わりに、無名のインライ
ンソートルーティンとして、block を書くことができます。
効率化のために、このサブルーティンでは、通常の呼び出し処理は行なわれず、 以下のような制約があります。このサブルーティンは、再帰サブルーティンであっ てはなりません。比較のためサブルーティンに渡される 2 つの要素は、@_ で はなく、$a と $b で渡されます (次の例を参照してください)。これらはリファ レンスによって渡されるので、$a や $b を変更しないでください。
例:
# 文字の順でソート
@articles = sort @files;
# 同じことを明示的にソートルーティンを指定して
@articles = sort {$a cmp $b} @files;
# 同じことを逆順に
@articles = sort {$b cmp $a} @files;
# 数値の昇順にソート
@articles = sort {$a <=> $b} @files;
# 数値の降順にソート
@articles = sort {$b <=> $a} @files;
# サブルーティン名を指定してソート
sub byage {
$age{$a} <=> $age{$b}; # 整数を仮定
}
@sortedclass = sort byage @class;
sub backwards { $b cmp $a; }
@harry = ('dog','cat','x','Cain','Abel');
@george = ('gone','chased','yz','Punished','Axed');
print sort @harry;
# AbelCaincatdogx と出力
print sort backwards @harry;
# xdogcatCainAbel と出力
print sort @george, 'to', @harry;
# AbelAxedCainPunishedcatchaseddoggonetoxyz と出力
push(@a,$x,$y) splice(@a,$#a+1,0,$x,$y) pop(@a) splice(@a,-1) shift(@a) splice(@a,0,1) unshift(@a,$x,$y) splice(@a,0,0,$x,$y) $a[$x] = $y splice(@a,$x,1,$y);
次の例では、配列の前に、それぞれの配列の大きさが渡されるものとしています:
sub aeq { # 2 つのリスト値を比較する
local(@a) = splice(@_,0,shift);
local(@b) = splice(@_,0,shift);
return 0 unless @a == @b; # 長さは等しいか
while (@a) {
return 0 if pop(@a) ne pop(@b);
}
return 1;
}
if (&aeq($len,@foo[1..$len],0+@bar,@bar)) { ... }
リストコンテキストでない場合には、見つかったフィールドの数を返し、配列
@_ に分割結果を設定します。(リストコンテキストでは、パターンの区切り文
字に ?? を使うことで、強制的に @_ に分割結果を残すことができますが、返
却値は配列値のままです。)しかし、暗黙の @_への split は使わない
ようにしてください。
expr を省略すると、文字列 $_ を split します。もし、
pattern も省略すると、空白 (/[ \t\n]+/) で split します。
pattern にマッチするものは、フィールドを分割するデリミタとして扱わ
れます。(デリミタは、1 文字とは限りません。)負でない limit を指定
した場合には、最大その数までのフィールドに split します (しかし、
それより少ないことはあります)。limit を指定しないと、末尾の空フィー
ルドを捨ててしまいます (pop() を行なうときには気を付けないといけ
ません)。limit が負ならば、limit に任意の大きな数を指定した
のと同じことになります。
空文字列にマッチするパターン (ヌルパターン // と混同しないでください。こ れは、空文字列にマッチするパターンの一つでしかありません) は、どの場所に もマッチし、expr の値を1 文字ずつに分割します。たとえば、
print join(':', split(/ */, 'hi there'));
は、'h:i:t:h:e:r:e' という出力になります。
limit を使うと、行を部分的に split することができます。
($login, $passwd, $remainder) = split(/:/, $_, 3);
リストへ代入するとき、limit を省略すると、Perl は、無駄な仕事を避 けるため、そのリストの変数の数より、1つだけ大きい limit が与えられ たものとして処理を行ないます。上のリストの場合には、limit はデフォ ルトで 4 になります。時間が問題となるアプリケーションでは、必要以上のフィー ルドに分けないようにする必要があります。
pattern に括弧が含まれていると、デリミタ内の部分文字列にマッチする ものも、配列要素に含まれるようになります。
split(/([,-])/, "1-10,20");
は、リスト値
(1, '-', 10, ',', 20)
を生成します。
`/PATTERN/' は、実行時に変わるパターンを指定する式で置き換えること
ができます。(実行時のコンパイルを 1 度にするために、`/$variable/o'
を使ってください。) 特別な場合として、スペース (' ') を指定すると、引数
なしの split のように空白で split を行ないますが、先頭の空
白で、最初に空のフィールドができません。つまり、split(' ') は、
awk のデフォルトの動作をエミュレートするために使うことができ、
split(/ /) は行頭のスペースの数に応じた空フィールドができます。
例:
open(passwd, '/etc/passwd');
while (<passwd>) {
($login, $passwd, $uid, $gid,
$gcos, $home, $shell) = split(/:/);
...
}
(上記の $shell には、まだ改行がついたままです。このドキュメントの
chop、chomp、join の項を参照してください。)
shift の逆操作を行ないます。見方を変えれば、push の逆操作
とも考えられます。list を array の先頭に入れて、新しくできた
配列の要素の数を返します。
unshift(ARGV, '-e') unless $ARGV[0] =~ /^-/;
list は、はらばらにではなく、一度に登録されるので、順番はそのまま
です。逆順に登録するには、reverse を使ってください。
keys() 関数や
each() 関数が返すものと同じ順序です。keys() と
each() も参照してください。
Go to the first, previous, next, last section, table of contents.