>我在系统托盘小程序中有以下初始化代码:
use Gtk3 -init;
use Glib::Object::Introspection;
eval {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
};
if ($@) {
say "no notify because setup failed: $@";
$use_notify = 0;
} else {
MyProgram::Notify->init();
}
该代码基于 fdpowermon,但似乎或多或少来自 Glib::Object::Introspection 的 POD 中的异常处理示例。
但是perlcritic(在第3级)对此进行了争论:
Return value of eval not tested at line …
所以我试图用 Try::Tiny 重写它:
use Gtk3 -init;
use Glib::Object::Introspection;
use Try::Tiny;
try {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
} catch {
say "no notify because setup failed: $@";
$use_notify = 0;
} finally {
if (!$@) {
MyProgram::Notify->init();
}
}
但随后 perl 认为:
Can't locate object method "new" via package MyProgram::Notify::Notification
虽然我确实看到特别是finally
块并不是一个真正的改进,但我不明白为什么使用 Try::Tiny 对 Glib::Object::Introspection 创建的包有如此大的影响。
或者有没有比 Try::Tiny 更好的方法让这段代码更优雅、更易读,同时让perlcritic
满意?
批评的重点在于避免检查$@
,因为它可能会被破坏。然而,在您进行所有更改之后,您仍在检查$@
!
更糟糕的是,Try::Tiny将错误放在$_
中,而不是$@
中,并且只放在catch
块中。
我认为正在发生的事情是,由于上述错误,MyProgram::Notify->init()
在不应该调用的时候被调用。
修复:
my $use_notify = 1;
try {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
MyProgram::Notify->init();
} catch {
say "no notify because setup failed: $_";
$use_notify = 0;
}
或
my $use_notify = 1;
try {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
} catch {
say "no notify because setup failed: $_";
$use_notify = 0;
}
MyProgram::Notify->init() if $use_notify;
无需尝试::微小:
my $use_notify = 1;
if (!eval {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
MyProgram::Notify->init();
1; # No exception
}) {
say "no notify because setup failed: " . ( $@ // "Unknown error" );
$use_notify = 0;
}
或
my $use_notify = 1;
if (!eval {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => "MyProgram::Notify",
);
1; # No exception
}) {
say "no notify because setup failed: " . ( $@ // "Unknown error" );
$use_notify = 0;
}
MyProgram::Notify->init() if $use_notify;
实际上,我的问题的答案与此基本相同:catch
(或者更确切地说是finally
)块后面缺少分号。
对不起,噪音。