user6403276 user6403276 - 3 months ago 6x
Perl Question

Operator to read a file using file handle

I am trying to read a file,

while($line = $file_handle)

When I ran this code, the program hung.

I noticed to read the file using file handle, we need to used <>

while($line = <file_handle>)

The later code obviously ran.

Now I know operator <> is to read the file line by line, I want to know what exactly is happening when I dont provide <> operator?
Is it not able to find the end of the line ?or?



Short   File is read by the <> operator so without it it is only an assignment, thus the infinite loop.

The while (...) { ... } checks the condition inside () and if true it executes the body in the block {}. It keeps doing this until the condition in () evaluates to what is understood as false (generally 0, '0', '', or undef). This is what the operator <> provides, for example, so we have an idiom

while (my $line = <$file_handle>) { ... }

The <> operator reads a line at each iteration from the resource that $file_handle is associated with and when it reaches end-of-file it returns undef so the loop terminates and the program execution continues at the next statement after the loop. The diamond operator <> is the operator form for the function readline. See I/O Operators in perlop. For all this to work $file_handle has to be a valid resource that can retrieve data.

Without the <> operator nothing is read from anywhere, but there is only an assignment. The code does the following. It copies the variable $file_handle into the variable $line. The return value of that operation in Perl is the value that ends up in $line, and if that is a 'truthy' value then the body { ... } is executed. The $file_handle clearly evaluates to 'true', otherwise the loop body would not execute even once and the program would continue. Thus $line is true, too. So if the $file_handle doesn't change in the body {...} of the loop the condition is always true.

Then whatever is in the body keeps being executed, without a reason for the loop to terminate, and it thus never returns control to the program. It's an infinite loop, and the program appears to hang.

Note that this is sometimes used deliberately and you may see code like

while (1) {
    # Compute what is needed
    # Recalculate the condition for when to stop
    last if $condition_to_terminate;

This approach can be risky though, since the condition can get more and more complicated and an error could sneak in, in which case we end up with an infinite loop. There are usually clearer ways to control loops.

A completely different example is an event loop, where it is crucial to enter an infinite loop so that we can then wait for an event of some sort, at which point a particular action is taken. This is how GUI's work, for example, and a number of other systems.