我有一个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';
是否可以做这样的事情,如果是的话,怎么做?
答案 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)
。
如果你在模块中有一堆例程都采用相同的输出文件句柄,那么一直传递它会变得乏味。而是创建一个对象:
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
值。这将使子程序调用工作(不会践踏彼此的设置)只要每个更改它的子程序首先将其本地化。
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之前去,那么你就是独自一人。