全局文件句柄

Gay*_*ane 0 perl file

我需要在几个perl模块中使用相同的文件句柄.这是我的例子a.pl

#!/usr/bin/perl -w

our $OUT_FILE_HANDLE;

require b;

open($OUT_FILE_HANDLE, ">./a.log");
print $OUT_FILE_HANDLE "text1\n";

b::f($OUT_FILE_HANDLE); // this works
Run Code Online (Sandbox Code Playgroud)

b.pm

package b;

sub f($) {
  my $a = shift;
  print $a "text2\n";  // get error here
}

f($main::OUT_FILE_HANDLE);
1;
Run Code Online (Sandbox Code Playgroud)

我收到错误"不能使用未定义的值作为符号引用"

如果我直接在b.pm中使用句柄(不将其作为参数传递给函数),它可以正常工作

b.pm

package b;

sub f() {
  print $main::OUT_FILE_HANDLE "text2\n";  // this works
}

f();
1;
Run Code Online (Sandbox Code Playgroud)

小智 9

您的示例因执行顺序而失败:所有b.pm都在您执行时执行require b;.因此,您尝试在打开文件句柄之前使用它.

作为一般原则,模块应该只通过可以调用的函数来完成.只有在需要模块时才应运行初始化事务.

在这种情况下,最好的设计是使用词法文件句柄并将其传递给任何需要它的函数.不要使用全局.

open(my $OUT_FILE_HANDLE, '>', './a.log') or die "Ouch: $!";
print $OUT_FILE_HANDLE "text1\n";

b::f($OUT_FILE_HANDLE);
Run Code Online (Sandbox Code Playgroud)

使用全局变量与模块进行通信很少是一个好主意.偶尔,模块将全局暴露给调用代码可能是有用的,但反过来从来都不是一个好的设计.模块不应依赖于特定包中存在的特定变量才能工作.

最后,你几乎不应该在Perl中使用子程序原型.只要省略原型,除非你了解所有关于Perl原型并且有充分的理由使用它们:

sub f {
Run Code Online (Sandbox Code Playgroud)