尝试{}阻止后内部状态更改

时间:2013-06-19 20:49:07

标签: perl object try-catch state marpa

我正在使用Marpa::R2,并尝试使用Try::Tiny捕获错误。我很困惑,因为当我将解析代码放入try块时,value方法的结果是undef。这是我的代码:

use strict;
use warnings;
use Marpa::R2;
use Data::Dumper;
use Try::Tiny;

my $grammar = Marpa::R2::Scanless::G->new(
    {
        source => \(<<'END_OF_SOURCE'),
            :default ::= action => ::array
            :discard ~ ws
            ws ~ [\s]+
            :start ::= Name
            Name ::= Foo
            Foo ~ [\w]+
END_OF_SOURCE
    }
);
my $reader = Marpa::R2::Scanless::R->new(
    {
        grammar => $grammar,
    }
);
my $input = 'foo';
try{
    $reader->read(\$input);
}catch {
    warn "caught error: $_";
}
my $value = $reader->value;
print Dumper $value;

我试图弄清楚语法是什么,我有点疯狂,然后我意识到删除try块会使$reader->value的值为非空。即使我在$value块中分配try,块结束时也会变为undef

my $value;
try{
    $reader->read(\$input);
    $value = $reader->value;
}catch {
    warn "caught error: $_";
}
print Dumper $value;

这似乎意味着如果我想用Try::Tiny捕获错误,我必须将$value的所有处理放入try块,这很不方便。

任何人都可以告诉我是什么导致了这个问题(我想解释一下这在Perl中是如何实现的)?有没有办法解决它?

1 个答案:

答案 0 :(得分:4)

try{
    $reader->read(\$input);
}catch {
    warn "caught error: $_";
}                               <------ missing semicolon
my $value = $reader->value;

请记住,try实际上不是控制结构。 trycatch只是&@原型的替代品。 (我想catch会返回某种形式的对象。)因此,上面的代码等同于

&try(sub { ... }, &catch(sub { ... }, my $value = $reader->value));

请注意$value

之前如何完成try的作业