如何将文件句柄传递给Perl子程序?

时间:2012-06-19 17:44:45

标签: perl subroutine filehandle

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

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

有谁知道我怎么做到这一点?我很感激任何建议。

2 个答案:

答案 0 :(得分:6)

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

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

如果你真的只需要获取完整的文件内容,这应该是首选关闭打开的文件句柄的好习惯。

使用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;

答案 1 :(得分: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.