2017-10-14 1 views
2

Ich versuche, ein paar Funktionen zu erstellen, die zusammenarbeiten werden. getFH sollte in den Modus zum Öffnen der Datei (entweder > oder <) und dann die Datei selbst (von der Befehlszeile) nehmen. Es sollte überprüft werden, ob die Datei geöffnet werden kann, dann geöffnet und das Dateihandle zurückgegeben werden. doSomething sollte das Datei-Handle übernehmen und die Daten durchlaufen und alles tun. Allerdings, wenn die Programmzeilen der while-Schleife, ich den Fehler:Dateihandle von Subroutine zurückgeben und an andere Subroutine übergeben

readline() on unopened filehandle 1

Was mache ich hier falsch?

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

Antwort

3
my $fh = @_; 

Diese Linie bedeutet nicht, was Sie denken, es bedeutet. Es setzt $fh zu die Anzahl der Elemente in @_ anstelle des übergebenen Dateihandles - wenn Sie den Wert $fh drucken, wird es 1 anstelle eines Dateihandles sein.

Verwenden Sie stattdessen my $fh = shift, my $fh = $_[0] oder my ($fh) = @_.

+0

Ah, ich wusste, dass es etwas Einfaches wie das war. Danke @Dave Sherohman, der sich immer noch wieder mit Perl anfreundete. Den ganzen Sommer über in R programmieren zu können –

2

Wie bereits erwähnt, setzt my $fh = @_$fh auf 1, was kein Datei-Handle ist. Verwenden

my ($fh) = @_ 

statt Listenzuordnung verwenden

Zusätzlich

  • -e -f -r -w $file nicht tun, was Sie wollen. Sie müssen

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

    Und Sie können dies prägnanter und effizienter gestalten, indem _ anstelle der Dateinamen unterstreichen verwenden, die die Informationen geholt für die vorherige Datei Test erneut verwenden

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

    jedoch Beachten Sie, dass Sie eine Anfrage zurückweisen, wenn eine Datei nicht schreibbar ist, was keinen Sinn ergibt, wenn die Anfrage darin besteht, eine Datei zum Lesen zu öffnen. Außerdem kehrt -ffalsch, wenn die Datei nicht existiert, so -e ist überflüssig

  • Es ist gut $! in Ihrem die Strings enthalten, wie es enthält den Grund für das Scheitern, aber die ersten beiden Prüfungen durch diesen Wert nicht auf, und so sein sollte zusätzlich nur die "Read or Write symbol not provided"; usw.

    In, die "Cannot open $file", $! wahrscheinlich

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

    deutlich zu machen, wenn der Dateiname leer ist, und etwas Platz zwischen der Botschaft und dem Wert von $!

  • Die Zeilen lesen aus der Datei hinzuzufügen, werden ein Newline-Zeichen am Ende haben, so gibt es keine Notwendigkeit für say.Einfach ist print while <$fh> feine

  • Perl Variablennamen sind konventionell snake_case, so get_fh und do_something ist üblicher

+1

Danke für die Aufmerksamkeit @Borodin! Sehr geschätzt. –

+1

Dank @Dave ist es behoben – Borodin

Verwandte Themen