in reply to Re: Question on File Handler and Subroutines in Perl
in thread Question on File Handler and Subroutines in Perl

Hi Marshall,

Thank you for your help on this! :)

I have tried to do what you have told me, i.e.

Write a program that opens FileA.txt and then prints all lines that contain "asdf". Create FileA.txt with test cases as you wish.

My program is seen below:
#!/usr/bin/perl use strict; use warnings; sub open_file { my $file = shift; my $pattern = "asdf"; open FILE, $file; while (my $line = <FILE>) { if ($line =~ m/$pattern/){ print $line; } } } open_file@ARGV

Hence in the command line (Terminal), I did a: ./open_file.pl FileA.txt, and the printouts were correct.

Replies are listed 'Best First'.
Re^3: Question on File Handler and Subroutines in Perl
by Anonymous Monk on Mar 05, 2019 at 09:37 UTC

    Hi NetWallah, Marshall and members of the PerlMonk community,

    Thank you all for your kind help and support. I have managed to solve the question, thanks to an inspiration by Marshall.

    My code is shown below:

    #!/usr/bin/perl use strict; use warnings; sub grep_file { my @files = @_; my $pattern = "asdf"; foreach my $file (@files) { open FILE, $file; while (my $line = <FILE>) { if ($line =~ /$pattern/) { print $line; } } } } grep_file @ARGV
    Thank you all once again! (:
      Another tip for you,
      open FILE, $file;
      better written as:
      open FILE, '<', $file or die "unable to open $file for reading $!";
      The three argument version of open where the open mode (read,write,append) is explicitly specified has some advantages. With just 2 arguments, if somehow $file was say ">somefile", the open would clobber the contents of "somefile". Specifically saying that this is an "open for the purpose of reading" prevents that. The die message, terminates the program with some printed reason, $! gives additional O/S info, perhaps "permission denied", "file does not exist" or something. In a more complex app, I try to explain to the user in terms that they understand what this file that failed to open is "configuration file", "Club Roster Spreadsheet" or whatever in addition to the actual file name. This can be very helpful for the user.

      Also it is possible to use a lexical variable for the file handle instead of a label like FILE which is global in scope.

      open my $config_fh , '<', $file or die "unable to open Configuration $ +file for reading $!";
      In a small one pager, I often don't worry about this. However in longer programs this can be important- I would pass the lexical file handle to a subroutine rather than relying upon a global value. Also note that the lexical file handle will be closed if it goes out of scope.

      As a final note: in the die message, if you end it with an explicit "\n", like "some message $!\n", that suppresses the Perl code line number from the message. I sometimes do that in programs written for absolute non-computer types as that extra info can confuse them and subtract from the main error message!