I wrote a script that prints the current and subsequent line after a match, however, I've noticed a difference between two ways of using the readline
return value.
This works as intended:
$ echo $'H1\na\nb\nH2\na\nb' | perl -ne 'if (/^H/) { print; print $line = readline }'
H1
a
H2
a
However, this doesn't:
$ echo $'H1\na\nb\nH2\na\nb' | perl -ne 'if (/^H/) { print; print readline }'
H1
a
b
H2
a
b
instead, it prints all the lines. Why?
CodePudding user response:
print
takes a list argument, and puts readline()
in list context. Hence it exhausts all of the lines. When you use scalar assignment with $line =
it is in scalar context, and will only read 1 line.
Read more about context here.
CodePudding user response:
The context in which readline
is called is different.
In $line = readline
, =
is the scalar assignment operator, and it evaluates its operands in scalar context. In scalar context, readline
returns a single line.
print
, on the other hand, accepts an expression which it evaluates in list context. In list context, readline
returns all remaining lines.
Equivalent:[1]
$line = readline; print $line;
print $line = readline;
print scalar(readline);
- If
$line
isn't magical. Except for the effect on$line
.