2

I've seen that close ARGV can close the currently processed file, but it would seem that ARGV isn't actually a file handle, so I can't use it in a read call. Is there any way to get the current file handle, or am I going to have to explicitly open the files myself?

Adrian
  • 10,246
  • 4
  • 44
  • 110
  • 1
    *...but it would seem that ARGV isn't actually a file handle* -- That is incorrect. If you had shown us the code that led you to this incorrect conclusion, we might have been able to help you solve your issue. Though I have to say if you are using `read` to read from the filehandle, then using ARGV is a poor choice. `<>` and `` uses readline and the input record separator to determine buffer size, whereas read() uses user specified size. It is two different ways of reading files – TLP Nov 20 '22 at 16:38

2 Answers2

5

... but it would seem that ARGV isn't actually a file handle, so I can't use it in a read call

ARGV is a filehandle and it can be used within read.

To cite from perlvar:

... a plain filehandle corresponding to the last file opened by <>"*

So it is a filehandle and it can be used within read. But you need to have to use <> first so that the file gets actually opened. And it will not magically continue with the next file as <> would do.

To test simply do (UNIX shell syntax, you might need to adapt this for Windows):

perl -e '<>; read(ARGV, my $buf, 10); print $buf' file

The <> will open the given file and read the first line. The read then will read the next 10 bytes from the same file.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Oh, good to know. What does _"... Note that currently ARGV only has its magical effect within the <> operator ..."_ mean? As in you can use `` instead of `<>`? – Adrian Nov 20 '22 at 14:57
  • 1
    @Adrian: Yes, you could also write `` instead of `<>`. And `<>` is the only place where the magic of opening the next file and reassigning `ARGV` is. – Steffen Ullrich Nov 20 '22 at 14:58
  • Re "*`<>` is the only place where the magic of opening the next file and reassigning `ARGV` is.*", Not quite. `readline` is the only place, though`<...>` can be a shortcut for `readline`. – ikegami Nov 29 '22 at 19:46
  • @ikegami: I think the documentation would need to be updated then since it states *"Note that currently "ARGV" only has its magical effect within the "<>" operator; elsewhere it is just a plain filehandle corresponding to the last file opened by "<>"."* – Steffen Ullrich Nov 29 '22 at 21:15
  • 1
    Apparently so. There is no `<>` operator in the "Perl machine", only in the Perl grammar. `<...>` gets compiled into `glob` or `readline`. And there's no flag to indicate that the `<...>` syntax was used. The logic is (only) in the `readline` operator of the "Perl machine". Whether you get there by using `<...>` or `readline` is irrelevant. – ikegami Nov 29 '22 at 21:20
3

<> is short for readline( ARGV ).

The file handle used is ARGV.

However, readline has special code to open/reopen ARGV which read doesn't have.

You can, however, achieve a read using readline by manipulating $/.

$ echo abcdef | perl -Mv5.14 -e'local $/ = \2; $_ = <>; say "<<$_>>";'
<<ab>>

$ perl -Mv5.14 -e'local $/ = \2; $_ = <>; say "<<$_>>";' <( echo abcdef )
<<ab>>
ikegami
  • 367,544
  • 15
  • 269
  • 518