2017-10-14 14 views
2

私は一緒に機能する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の値を印刷する場合、それは代わりにファイルハンドルの1になります - それは@_内の項目の数ではなく、中に渡されたファイルハンドルをする$fhを設定します。

my $fh = shift,my $fh = $_[0]またはmy ($fh) = @_を代わりに使用してください。

+0

ああ、私はそれがそのような単純な何かを知っていました。ありがとう@Dave Sherohman、まだPerlで快適になっています。すべての夏にRでプログラミングされています –

2

指摘したように、my $fh = @_は、$fhを1に設定します。これはファイルハンドルではありません。

  • -e -f -r -w $fileまたリスト代入

    を使用する代わりに

    my ($fh) = @_ 
    

    を使用して、あなたがやりたいことはありません。しかし

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

    前回のファイルテストのために再利用する情報フェッチされた、あなたは

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

    を必要としますが、ファイル名の代わりに_を強調使用して、これはより簡潔かつ効率的に行うことができますファイルが書き込み可能ではない場合、要求を拒否することに注意してください。要求が読み取りのためにファイルを開くことは意味がありません。ファイルが存在しない場合にも、-fので-eは不必要である、を返します

  • それは失敗の理由が含まれているとして、あなたのdie文字列で$!を含めるのは良いですが、あなたの最初の2テストは、この値を設定しないと、これだけ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

頭のおかげで@ボロディン!大変感謝しています。 –

+1

ありがとう@Dave it's fixed – Borodin

関連する問題