Perl の pos
はどういう時に初期化されるのかを実験してみた。
Perl の pos $var
は変数 $var
に対してする次回の正規表現マッチングの開始位置を示すプロパティを取り出したり、設定したりするのに使うための仕組み。このプロパティは $var
に対して m/正規表現/g
のマッチングをすると更新される。そして $var
に代入操作がある場合には初期化されて undef
になる。だけど、$var
に対してまったく同じ値を入れたらどうなる?今回はそれを調べてみた。
テストコード
$ABC = 'A B C' ;
{
my $var = $ABC ;
$var =~ m/\s/g ; # 👈マッチングで pos を更新する。この場合は「2」になる。
$p = pos $var ;
$var = $ABC ; # 👈👈 pos は代入で更新される。ここをいろいろ替えてるのが今回の実験!
$q = pos $var ;
say '[$var = $ABC] => ', ($p eq $q ? 'Not Initialized' : 'Initialized') ;
}
結果
マッチング m/\s/g
の後に $var
に、色々なやりかたで同じ値を代入してみて(「👈👈」の箇所を振って)、pos $var
が初期化されるかどうかを確かめてみた。
初期化されなかったもの | 初期化されたもの |
---|---|
|
|
規則性?
よく分からないけども、$var
そのものの評価が必要となった場合に、$var
の値が元のものとは違うという扱いをされているようだということ。
面白いというのか、よくわからないのは…
-
$var = $var = $var ;
は値に変化がないという扱いを受けている一方で、$var = $xyz = $var ;
は値が変化しているという扱いを受けたているという点。 -
($var) = ($var) ;
は値が変化しているという扱いを受けている一方で、$var = scalar $var ;
とか… ? $var : $var
とか… && $var
は値に変化がないという扱いを受けている点。
最適化とも関係がありそうな気がする。となると Perl の処理系のバージョン次第では異なる可能性もありそうだ。$var = "$var" ;
でさえ今後のバージョンの最適化次第では $var = $var ;
と同じ扱いを受けるようになる可能性もあるかもしれない。これはちょっと厄介だ…。
補遺 -- Perl バージョン
% perl -v
This is perl 5, version 40, subversion 2 (v5.40.2) built for x86_64-cygwin-threads-multi
(with 3 registered patches, see perl -V for more detail)
Copyright 1987-2025, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.
%