perl使用已使用模块上的文件句柄

时间:2012-01-20 16:18:08

标签: perl

我有一个perl模块module.pm和一个调用script.pl的{​​{1}}文件 module.pm是否可能知道在module.pm内声明的文件,例如:

我在script.pl下面有一个文件定义

script.pl

in module.pm我想使用FILE句柄,例如:

use module;
open FILE,'>','file.txt' or die 'can\'t open file';

是否可以做这样的事情,如果是的话,怎么做?

3 个答案:

答案 0 :(得分:5)

如果您使用词汇文件句柄而不是Barewords,则可能。

use module ;
open( my $filehandle , '>' , 'output.txt' ) or die 'Cannot open.' ;
module::some_fun( $filehandle ) ;

并在module.pm

package module ;
sub some_fun {
  my ( $filehandle ) = @_ ;
  print $filehandle "Hello world.\n" ;
}
1 ;

希望有所帮助。

答案 1 :(得分:3)

如果你不use strict,可能会这样做,但这是非常糟糕的做法。更好的选择是将文件句柄传递给module.pm方法/函数。

use module;
open my $FILE,'>','file.txt' or die 'can\'t open file';

somesub($FILE);

然后:

package module;

sub somesub {
    my $FILE = shift;
    ... 
}

答案 2 :(得分:3)

正如弗利奇回答的那样,你不应该这样做。有更好的方法来完成你想要完成的任何事情。我将在一秒钟内介绍一些。

您可以在与包不同的命名空间中打开文件,或打印到一个文件:

package module;
print main::FILE "some text\n";

或者,在你的程序中:

open(module::FILE, '>', '/tmp/file');

您可以使用caller来查找调用者的包(而不是仅仅假设为main)。这样,你总是可以使用来电者的文件。

更好的方式

存储在变量

中的匿名文件句柄

你现在应该使用存储在标量中的globs。换句话说,您的公开呼叫应如下所示:

open my $file, '>', '/tmp/file'

然后$file是一个普通的标量,你可以像传递任何其他变量一样传递它。所以,也许你的模块中有这个代码:

package module;
sub foo {
    my $dest = shift;
    print $dest "hello, world\n";
}
1;

然后在你的程序中,在打开之后,你会打电话给module::foo($file)

匿名文件句柄和OO

如果你在模块中有一堆例程都采用相同的输出文件句柄,那么一直传递它会变得乏味。而是创建一个对象:

package module;
use Moose;

has output_fh => (
    is => 'rw',
    required => 1,
);

sub foo {
    my $self = shift;
    print $self->output_fh "hello, world\n";
}

然后,在您的非模块代码中,您执行以下操作:

open my $fh, … ;
my $obj = module->new(output_fh => $fh);
$obj->foo();

当你开始在$obj中携带更多状态时,这种方法的优势就会增加。

匿名文件句柄和本地化包变量

如果您不想采用OO方法(通常比此方法更清晰),您可以在模块中执行此操作:

package module;
our $OUTPUT_FH = undef; # or sensible default

sub foo {
    print $OUTPUT_FH "hello, world\n";
}

然后在你的非模块代码中:

open my $fh, … ;
local $module::OUTPUT_FH = $fh;

module::foo();

local - 化将确保当您的当前块退出时,恢复之前的$module::OUTPUT_FH值。这将使子程序调用工作(不会践踏彼此的设置)只要每个更改它的子程序首先将其本地化。

如果您必须使用5.6之前的perl:

Perl 5.6(大约12年前发布的2000-03-22)引入了文件句自动更新,使open my $fh, …行正常工作。在早期版本中,您需要自己制作glob。 Symbol模块提供了一种简单的方法:

use Symbol qw(gensym ungensym);
my $fh = gensym; # not sure if pre-5.6 had geniosym; if so, use that instead
open $fh, …
⋮
close $fh;
ungensym $fh;

如果你想在1995年变得稳定的perl 5之前去,那么你就是独自一人。