2017-10-14 97 views
2

我正在嘗試創建幾個可以一起工作的函數。 getFH應採用打開文件的模式(><),然後是文件本身(從命令行)。它應該做一些檢查,看看文件是否可以打開,然後打開它,並返回文件句柄。 doSomething應該接受文件句柄,並循環數據並執行任何操作。但是,當程序行到while循環,我得到的錯誤:從子程序返回文件句柄並傳遞給其他子例程

readline() on unopened filehandle 1

我在做什麼錯在這裏?

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

回答

3
my $fh = @_; 

此行並不意味着你認爲這意味着什麼。它將$fh設置爲@_中的項目數,而不是傳入的文件句柄 - 如果您打印的值爲$fh,則它將是1而不是文件句柄。

改爲使用my $fh = shift,my $fh = $_[0]my ($fh) = @_

+0

啊,我知道這是一些簡單的類似。感謝@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將返回如果文件不存在,所以-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是更常見的

+1

感謝@Borodin的領導!不勝感激。 –

+1

謝謝@Dave它是固定的 – Borodin