-1

我在系统托盘小程序中有以下初始化代码:

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快乐?

4

2 回答 2

3

批评的重点是避免检查$@,因为它可能已被破坏。然而,在您进行了所有更改之后,您仍在检查$@

更糟糕的是,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;

没有 Try::Tiny:

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;
于 2017-01-28T02:14:03.643 回答
0

实际上我的问题的答案与这个问题的答案基本相同catch:(或更确切地说finally)块后面缺少分号。

对不起,噪音。

于 2017-01-28T02:46:04.767 回答