変数展開は毎回必要か

back
o オプション

パターンに変数を書いた場合に、ループ内や g オプションで何度も
同じパターンマッチが呼ばれる場合は、毎回変数が展開される。

# 1. $target が、@list のパターンにマッチするか調べる

@list = qw/pattern1 pattern2 pattern3 pattern4 pattern5/;
$target = "なんとか";

foreach $pattern (@list) {
  if ($target =~ m/$pattern/) {
    print "match\n";
  }
  else {
    print "unmatch\n";
  }
}

これは問題ない。(毎回パターン内容が変わっている必要があるため)


# 2. @list のなかから、$pattern にマッチするものを調べる

@list = qw/target1 target2 target3 target4/;
$pattern = "なんとか";

foreach $target (@list) {
  if ($target =~ m/$pattern/) {
    print "match\n";
  }
  else {
    print "unmatch\n";
  }
}

これは、パターン $pattern が毎回同じことが(コーディングする人間は)わかっている。
が、実行時は、ループ内でパターンマッチが行われる度に $pattern の内容が
評価されているため、ムダ。

こーゆーときは、

if ($target =~ m/$pattern/o) {

とすれば、変数展開は最初の1回のみになって、以降は行われない。


ちなみに、case 1 のコードで o を付加しておくと、ループのたびに @list からセットされる
$pattern がどんなに変化しても、パターンマッチの部分だけは、@list から最初にセットされた
$list[0] の値になってしまう。


--------
$target = "pattern1";
@list = qw/pattern1 pattern2 pattern3 pattern4 pattern5/;
foreach $pattern (@list) {
  print "target:($target) pattern:($pattern)   ";
  if ($target =~ m/$pattern/o) {
    print "match\n";
  }
  else {
    print "unmatch\n";
  }
}
---------
結果

target:(pattern1) pattern:(pattern1)   match
target:(pattern1) pattern:(pattern2)   match
target:(pattern1) pattern:(pattern3)   match
target:(pattern1) pattern:(pattern4)   match
target:(pattern1) pattern:(pattern5)   match

back