我不知道“未定义的行为”在Perl中是否意味着什么,但我想知道在Perl中使用未初始化的变量是否会引发不必要的行为。
让我们考虑以下脚本:
use strict;
use warnings FATAL => 'all';
use P4;
my $P4;
sub get {
return $P4 if $P4;
# ...connection to Perforce server and initialization of $P4 with a P4 object...
return $P4;
}
sub disconnect {
$P4 = $P4->Disconnect() if $P4;
}
sub getFixes {
my $change = shift;
my $p4 = get();
return $p4->Run( "fixes", "-c", $change );
}
在这里,变量$P4
(用于在连接到Perforce服务器后存储P4对象)在脚本开始时没有初始化。但是,不管首先调用的函数是什么(get
、disconnect
或getFixes
),变量在使用之前都会被初始化。
这样做有什么危险吗?应该在脚本开始时显式地初始化$P4
变量吗?
发布于 2021-04-30 11:59:32
用my
声明的变量使用undef
初始化。这里没有不明确的行为。
这在perldoc persub
中有记录。
如果没有为特定变量提供初始化器,则使用未定义的值创建该变量。
然而,奇怪的构造my $x if $condition
确实有未定义的行为。千万别那么做。
发布于 2021-04-30 17:56:58
my
将标量初始化为undef
,数组和散列为空。
您的代码很好,尽管我会采用不同的方法来销毁。
选项1:通过包装提供析构函数
use Object::Destroyer qw( );
use P4 qw( );
my $P4;
sub get {
return $P4 ||= do {
my $p4 = P4->new();
$p4->SetClient(...);
$p4->SetPort(...);
$p4->SetPassword(...);
$p4->Connect()
or die("Failed to connect to Perforce Server" );
Object::Destroyer->new($p4, 'Disconnect')
};
}
# No disconnect sub
选项2:通过猴子修补提供析构函数
use P4 qw( );
BEGIN {
my $old_DESTROY = P4->can('DESTROY');
my $new_DESTROY = sub {
my $self = shift;
$self->Disconnect();
$old_DESTROY->($self) if $old_DESTROY;
};
no warnings qw( redefined );
*P4::DESTROY = $new_DESTROY;
}
my $P4;
sub get {
return $P4 ||= do {
my $p4 = P4->new();
$p4->SetClient(...);
$p4->SetPort(...);
$p4->SetPassword(...);
$p4->Connect()
or die("Failed to connect to Perforce Server" );
$p4
};
}
# No disconnect sub
https://stackoverflow.com/questions/67333360
复制相似问题