3

我想要一个从特殊文件句柄中读取的 Perl 模块,并将其<STDIN>传递给子例程。当您看到我的代码时,您就会明白我的意思。这是以前的情况:

#!/usr/bin/perl
use strict; use warnings;

use lib '/usr/local/custom_pm'
package Read_FH

sub read_file {
my ($filein) = @_;
open FILEIN, $filein or die "could not open $filein for read\n";
# reads each line of the file text one by one
while(<FILEIN>){
# do something
}
close FILEIN;

现在,子例程将文件名(存储在 中$filein)作为参数,使用文件句柄打开文件,并使用精细句柄逐行读取文件的每一行。

相反,我想从中获取文件名<STDIN>,将其存储在变量中,然后将此变量作为参数传递给子例程。从主程序:

$file = <STDIN>;
$variable = read_file($file);

该模块的子程序如下:

#!/usr/bin/perl
use strict; use warnings;

use lib '/usr/local/custom_pm'
package Read_FH

# subroutine that parses the file
sub read_file {
my ($file)= @_;
# !!! Should I open $file here with a file handle? !!!!

# read each line of the file
while($file){
# do something
}

有谁知道我该怎么做?我很感激任何建议。

4

2 回答 2

6

一般来说,使用词法文件处理程序是一个好主意。那是一个包含文件处理程序而不是裸词的词法变量。

您可以像任何其他变量一样传递它。如果您使用read_filefrom File:: Slurp,则不需要单独的文件处理程序,它将内容 slurp 到变量中。

因为尽快关闭打开的文件句柄也是一种好习惯,如果您真的只需要获取完整的文件内容,这应该是首选方式。

使用 File::Slurp:

use strict;
use warnings;
use autodie;
use File::Slurp;

sub my_slurp {
    my ($fname) = @_;
    my $content = read_file($fname);

    print $content; # or do something else with $content

    return 1;
}

my $filename = <STDIN>;
my_slurp($filename);

exit 0;

没有额外的模块:

use strict;
use warnings;
use autodie;

sub my_handle {
    my ($handle) = @_;
    my $content = '';

    ## slurp mode
    {
        local $/;
        $content = <$handle>
    }

    ## or line wise
    #while (my $line = <$handle>){
    #    $content .= $line;
    #}

    print $content; # or do something else with $content

    return 1;
}

my $filename = <STDIN>;
open my $fh, '<', $filename;
my_handle($fh); # pass the handle around
close $fh;

exit 0;
于 2012-06-19T18:15:53.537 回答
3

我同意@mugen kenichi,他的解决方案比构建自己的解决方案更好。使用社区测试过的东西通常是个好主意。无论如何,这里是您可以对自己的程序进行的更改,以使其按照您的意愿行事。

#/usr/bin/perl
use strict; use warnings;

package Read_FH;

sub read_file {
    my $filein = <STDIN>;
    chomp $filein; # Remove the newline at the end
    open my $fh, '<', $filein or die "could not open $filein for read\n";
    # reads each line of the file text one by one
    my $content = '';
    while (<$fh>) {
        # do something
        $content .= $_;
    }
    close $fh;

    return $content;
}

# This part only for illustration
package main;

print Read_FH::read_file();

如果我运行它,它看起来像这样:

simbabque@geektour:~/scratch$ cat test
this is a
testfile

with blank lines.
simbabque@geektour:~/scratch$ perl test.pl
test
this is a
testfile

with blank lines.
于 2012-06-19T18:23:28.370 回答