【问题标题】:Return file handle from subroutine and pass to other subroutine从子程序返回文件句柄并传递给其他子程序
【发布时间】:2017-10-14 14:11:49
【问题描述】:

我正在尝试创建几个可以协同工作的函数。 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 $_;
    }
}

【问题讨论】:

    标签: perl filehandle


    【解决方案1】:
    my $fh = @_;
    

    这条线并不意味着你认为它的意思。它将 $fh 设置为 @_ 中的项目数 而不是传入的文件句柄 - 如果您打印 $fh 的值,它将是 1 而不是文件句柄.

    请改用my $fh = shiftmy $fh = $_[0]my ($fh) = @_

    【讨论】:

    • 啊,我就知道就是这么简单。感谢@Dave Sherohman,再次熟悉 Perl。整个夏天都在用 R 编程
    【解决方案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 &lt;$fh&gt; 就可以了

    • Perl 变量名通常是snake_case,所以get_fhdo_something 更常用

    【讨论】:

    • 感谢@Borodin 的提醒!非常感谢。
    • 感谢@Dave,它已修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多