从子程序返回文件句柄并传递给其他子程序

时间:2017-10-14 14:11:50

标签: perl filehandle

我正在尝试创建一些可以协同工作的函数。 getFH应该采用模式打开文件(><),然后是文件本身(从命令行)。它应该做一些检查,看看文件是否可以打开,然后打开它,并返回文件句柄。 doSomething应该接受文件句柄,并循环数据并执行任何操作。但是当程序排到while循环时,我收到错误:

  

未打开的文件句柄1上的readline()

我在这里做错了什么?

#! /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 $_;
    }
}

2 个答案:

答案 0 :(得分:3)

my $fh = @_;

这一行并不代表您认为的含义。它将$fh设置为 @_ 中的项目数而不是传入的文件句柄 - 如果您打印$fh的值,它将为{ {1}}而不是文件句柄。

改为使用1my $fh = shiftmy $fh = $_[0]

答案 1 :(得分:2)

正如已经指出的那样,my $fh = @_会将$fh设置为1,这不是文件句柄。使用

my ($fh) = @_

而是使用列表分配

另外

  • -e -f -r -w $file将无法满足您的需求。你需要

    -e $file and -f $file and -r $file and -w $file
    

    通过使用下划线_代替文件名,您可以使其更简洁有效,这将重新使用为先前文件测试获取的信息

    -e $file and -f _ and -r _ and -w _
    

    但是,请注意,如果文件不是可写,您将拒绝请求,如果请求是打开文件进行读取,则无效。此外,如果文件不存在,-f将返回 false ,因此-e是多余的

  • 最好在$!字符串中加入die,因为它包含失败的原因,但您的前两个测试不适用设置此值,因此应该只是die "Read or Write symbol not provided";等。

    此外,die "Cannot open $file", $!应该是

    die qq{Cannot open "$file": $!}
    

    清楚地说明文件名是否为空,并在消息和值$!之间添加一些空格

  • 从文件中读取的行最后会有换行符,因此不需要say。只需print while <$fh>就可以了

  • Perl变量名通常是 snake_case ,因此get_fhdo_something更常见