Search code examples
perlfilehandle

Return file handle from subroutine and pass to other subroutine


I am trying to create a couple of functions that will work together. getFH should take in the mode to open the file (either > or < ), and then the file itself (from the command line). It should do some checking to see if the file is okay to open, then open it, and return the file handle. doSomething should take in the file handle, and loop over the data and do whatever. However when the program lines to the while loop, I get the error:

readline() on unopened filehandle 1

What am I doing wrong here?

#! /usr/bin/perl

use warnings;
use strict;
use feature qw(say);

use Getopt::Long;
use Pod::Usage;

# command line param(s)
my $infile = '';
my $usage = "\n\n$0 [options] \n
Options
-infile         Infile
-help           Show this help message
\n";

# check flags
GetOptions(
    'infile=s' => \$infile,
    help       => sub { pod2usage($usage) },
) or pod2usage(2);

my $inFH = getFh('<', $infile);

doSomething($inFH);

## Subroutines ##

## getFH ##
## @params:
## How to open file: '<' or '>'
## File to open

sub getFh {
    my ($read_or_write, $file) = @_;
    my $fh;

    if ( ! defined $read_or_write ) {
        die "Read or Write symbol not provided", $!;
    }

    if ( ! defined $file ) {
        die "File not provided", $!;
    }

    unless ( -e -f -r -w $file ) {
        die "File $file not suitable to use", $!;
    }

    unless ( open( $fh, $read_or_write, $file ) ) {
        die "Cannot open $file",$!;
    }

    return($fh);
}

#Take in filehandle and do something with data

sub doSomething{
    my $fh = @_;

    while ( <$fh> ) {
        say $_;
    }
}

Solution

  • my $fh = @_;
    

    This line does not mean what you think it means. It sets $fh to the number of items in @_ rather than the filehandle that is passed in - if you print the value of $fh, it will be 1 instead of a filehandle.

    Use my $fh = shift, my $fh = $_[0], or my ($fh) = @_ instead.