Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of $/ in perl [closed]

Tags:

perl

I have seen many examples over Internet using $/ in perl over split but I couldn't understand the use.

Can any of you please explain how we use $/ over split in Perl?

like image 385
Prashant Tiwari Avatar asked Jul 29 '12 09:07

Prashant Tiwari


1 Answers

If you use readline $filehandle (or <$filehandle>) in scalar context, it will return the remainder of the unread part of the file up to and including the next occurrence of the string in $/. By default this is set to a newline, so the next line of the file is returned.

my $line = <$filehandle>

and

while (<$filehandle>) { ... }

both impose scalar context, so the variable is set to the next line of the file, and the loop executes with one line of the file at a time in the $_ variable.

Changing the value of $/ can sometimes be useful if the units of data in the file extend over several lines. For instance, if the file contains blocks that always end with a } at the end of a line then you can set $/ = "}\n". Then you will get everything up until the next end of block returned, possiibly with embedded newlines.

There are a couple of special values for $/. Setting it to an empty string with $/ = '' will make Perl return everything up until one or more blank lines in the file. Clearly this is useful only if the data in your file is separated into units with blank lines.

Setting $/ to undef will allow the read to continue right up to the end of file. This is what is meant by slurping the file into memory, and is sometimes practical for small files. If it is absolutely necessary it is best done using local within the confines of a small code block like

my $data = do {
  open my $filehandle, '<', 'file.txt' or die $!;
  local $/;
  <$filehandle>;
};

Setting $/ to a reference to a numeric value will force the read to stop after a specific number of characters. For instance $/ = \4096 will make readline fetch the next 4KB of data from the file for you (or the rest of the file if there is less than 4KB remaining). This could be used for special purposes like caching your own file reads.

By "Using $/ in Perl over split" I imagine you mean the difference between this and using split on the the entire file slurped into a scalar variable. The primary consideration is memory space. If the file is more than a few KB then it is very wasteful to read it all into a Perl variable at once if it isn't completely necessary. Using $/ and while will allow just one record at a time to be read into memory, processed, and discarded when the next record is read.

If you think you need all of the file in an array, so that you can look backwards as well as forwards for instance, you should consider the Tie::File module which will make it appear as if the entire file is in an array (and even let you modify it) but will actually be paging the data in and out of memory as necessary.

An advantage of using split is that it takes a regualr expression to identify the places to split the string. This is in contrast to $/ which may only be set to a simple string. If you need to divide the file up in more complex ways this may be useful.

In general, using $/ together with while is the best way to read a file and should be your first choice unless there is an overriding reason why you need something different. It will prevent extravagant memory usage and also encourage better programming by forcing you to concentrate on a single data record at a time.

like image 52
Borodin Avatar answered Sep 28 '22 08:09

Borodin