如何在 perl 子例程签名中设置默认文件句柄?
How can I set a default file handle in a perl subroutine signature?
我有一个子程序,
use experimental "signatures";
sub foo {
my $fh = +shift;
open ($fh, '>', 'default_file') unless defined $fh;
}
我想将其移植到子例程签名中。是否可以将 $fh 设置为默认指向 default_file
.
的文件句柄
像这样
sub foo ($fh=open($fh,">",foo")) {}
甚至 do{}
块,
sub foo ($fh=do { open($fh,">",foo"), $fh } ) {}
我知道如果我使用或创建一个包装器我可以获得这个语法。但似乎应该有某种方法可以在不调用 IO::File 之类的情况下完成此操作。
等待更好的答案,我认为唯一的方法是使用包装器,
use IO::File;
sub foo ( $fh=IO::File->new("default_file", "w") ) {
print $fh 42
}
您展示的第二次尝试几乎有效,您只需要另一个变量来代替,因为分配默认值时 $fh
尚不存在;并 return 它在声明它的地方的单独语句中。您当然可以滥用全局变量来执行此操作,但这很丑陋且有漏洞。
sub foo ($fh=do { open(my $d,">","foo"); $d } ) {}
这当然应该有错误处理。
sub foo ($fh=do { open(my $d,">","foo") or die "Failed to open 'foo': $!"; $d } ) {}
A proposed extension to signatures 可以用来做一些稍微不同的事情,但我不确定这是否更好:
sub foo (?$d, $fh=(open($d,">","foo") || die "Failed to open 'foo': $!", $d) ) {}
也可以作弊,只是一点点,使用无名无值optional argument
use experimental "signatures";
sub foo ($=) {
my $fh = shift;
open $fh, '>', "foo.txt" or die $! if not defined $fh;
say $fh 42;
return $fh;
}
从处理参数 "normally" 的意义上来说,这是伪造的(就像没有签名一样)。然而,签名的好处之一是 @_
保持原始状态,也可以使用
When using a signature, the arguments are still available in the special array variable @_
, in addition to the lexical variables of the signature.
我没有看到不使用它的充分理由。† 即使它将参数处理推回到子体中,您仍然可以获得签名的其他好处 - - 以及额外的灵活性措施。
† 处理签名中参数的风格点,包括它们的默认值,在这里无论如何都被拒绝了,仅仅因为这个默认值有多少要做。
我有一个子程序,
use experimental "signatures";
sub foo {
my $fh = +shift;
open ($fh, '>', 'default_file') unless defined $fh;
}
我想将其移植到子例程签名中。是否可以将 $fh 设置为默认指向 default_file
.
像这样
sub foo ($fh=open($fh,">",foo")) {}
甚至 do{}
块,
sub foo ($fh=do { open($fh,">",foo"), $fh } ) {}
我知道如果我使用或创建一个包装器我可以获得这个语法。但似乎应该有某种方法可以在不调用 IO::File 之类的情况下完成此操作。
等待更好的答案,我认为唯一的方法是使用包装器,
use IO::File;
sub foo ( $fh=IO::File->new("default_file", "w") ) {
print $fh 42
}
您展示的第二次尝试几乎有效,您只需要另一个变量来代替,因为分配默认值时 $fh
尚不存在;并 return 它在声明它的地方的单独语句中。您当然可以滥用全局变量来执行此操作,但这很丑陋且有漏洞。
sub foo ($fh=do { open(my $d,">","foo"); $d } ) {}
这当然应该有错误处理。
sub foo ($fh=do { open(my $d,">","foo") or die "Failed to open 'foo': $!"; $d } ) {}
A proposed extension to signatures 可以用来做一些稍微不同的事情,但我不确定这是否更好:
sub foo (?$d, $fh=(open($d,">","foo") || die "Failed to open 'foo': $!", $d) ) {}
也可以作弊,只是一点点,使用无名无值optional argument
use experimental "signatures";
sub foo ($=) {
my $fh = shift;
open $fh, '>', "foo.txt" or die $! if not defined $fh;
say $fh 42;
return $fh;
}
从处理参数 "normally" 的意义上来说,这是伪造的(就像没有签名一样)。然而,签名的好处之一是 @_
保持原始状态,也可以使用
When using a signature, the arguments are still available in the special array variable
@_
, in addition to the lexical variables of the signature.
我没有看到不使用它的充分理由。† 即使它将参数处理推回到子体中,您仍然可以获得签名的其他好处 - - 以及额外的灵活性措施。
† 处理签名中参数的风格点,包括它们的默认值,在这里无论如何都被拒绝了,仅仅因为这个默认值有多少要做。