x行目からy行目だけを処理する

back
範囲指定子をスカラコンテキストで評価する。

# 10 行目から 40 行目までを print
while (<FH>) {
  if (10 .. 40) {
    print;
  }
}

上記のように、定数を指定すると、自動的に $. と比較されて評価される。
変数を指定する場合で、行数を評価する場合は、明示的に
($. == $start .. $. == $end)
と書く。
(つまり、上のコードは ($. == 10 .. $. == 40) と同等)

この演算子 (x .. y) は、x の値・y の値・前回の自身の値の 3 つを元に、
真か偽のブール値を返す。
(9 行目までは x が偽なので、print されない)

初回評価時から、x が偽の場合は、y に関係なく式は偽であり、
一度 x が真になった場合に、式が真になる。
(10 行目では x が真になるので、print)

式が一度真になると、x に関係なく y が偽であれば、式は真でありつづける。
(11 行目から 39 行目までは x も y も偽なので、print)

式が真の状態で y が真になると、「範囲の終わり」であるフラグが付加されて
式は真になる。
(40 行目)
ちなみに、この「範囲の終わり」フラグは、式の戻り値(文字列)の末尾に "E0" と
付加される。

式が「範囲の終わり」の時に x が偽のままの場合、式が偽になる。
(41 行目以降が偽になる)


この演算子を使えば、行数以外にも次のような処理ができる。

■ ファイルの先頭から最初の空行までを処理
(メールのヘッダ部分を処理 など)
print if (1 .. /^$/);

■ ファイルの最初の空行から、ファイル末尾まで処理
(メールのボディ部分を処理 など)
print if (/^$/ .. eof());

など。
(これくらいしか例が思いつかないな…)



多分、こんな感じ
(1: 真 / 0: 偽 / 1E0: 範囲の終わり)

+---+1..0                         +----+
|   |0..0                         |    |0..0
|  +----+        1..0          +----+  |0..1
+->| 1  | <------------------- | 0  |<-+
   +----+                      +----+
   ^  |                         ^   |
   |  |                         |   |
   |  |                         |   |
   |  |                         |   |
   |  |0..1                 0..1|   |
   |  |1..1                 0..0|   |
   |  +-----> +----+ -----------+   |
   |          |1E0 |                |
   +--------- +----+ <--------------+
    1..0                 1..1

back