如何使Perl6死于未定义的值?

时间:2019-01-22 16:44:23

标签: perl6

我试图在Perl6中使用哈希,但是当我(故意)将一些假值放入其中时

say %key<fake_key>;

我知道

(Any)

但是我希望程序像Perl5那样在这种情况下死掉,因为这意味着重要数据丢失了。

例如,

#!/usr/bin/env perl

use strict;
use warnings 'FATAL' => 'all';
use autodie qw(:all);

my %hash;
print "$hash{y}\n";

从5.26.1开始产生

Use of uninitialized value $hash{"y"} in concatenation (.) or string at undefined.pl line 8.
Command exited with non-zero status 255

如何在Perl6中获得use warnings 'FATAL' => 'all'use autodie qw(:all)的等价物?

4 个答案:

答案 0 :(得分:12)

爱,您的问题是:

  

我正在Perl6中寻找use autodie qw(:all)use warnings 'FATAL' => 'all'

相当于P6中的autodie

P5中的Aiui use autodie qw(:all)在P6中变为use fatal;。这是一个词法作用域的效果。

The autodie section in the P5-to-P6 nutshell guide解释说,例程现在返回Failure来指示错误。

The fatal pragma使从例程返回Failure会自动引发包含Failure的异常。除非您提供捕获它们的代码,否则这些包裹Failure的异常会自动消失。

相当于P6中的use warnings 'FATAL'

P5中的Aiui use warnings 'FATAL' => 'all'在P6中变为CONTROL { when CX::Warn { note $_; exit 1 } }。这是一个词法作用域的效果。

CONTROL exceptions解释了它们如何工作。

CONTROL异常是默认情况下.resume引发的所有异常的子集-默认情况下,程序在抛出异常后仍保持活动状态。

我提供的P6代码(从您链接到的How could I make all warnings fatal?提起)反而使CONTROL异常死亡(由于exit例程)。

返回您当前的问题文本:

say %key<fake_key>; # (Any)
  

我希望程序在这种情况下死掉...

使用Jonathan ++的答案(使用put,与say不同的是,它不试图使程序保持活动状态)或Scimon ++的KeyRequired答案将访问非存在致命的关键。

  

...就像Perl5一样...

仅在使用use warnings 'FATAL' ...的情况下,就像使用P6的情况一样。

  

...,因为这意味着缺少重要数据。

通常它意味着不重要的数据丢失,或者甚至某些重要的数据在您尝试访问它们时都不想定义,因此Perls缺省使程序保持活动状态,并要求您告诉它想要的内容你想要不同的东西。

您可以使用上述构造来获取所需的精确结果,并且将它们限制为给定变量(如果使用KeyRequired角色)或语句(使用put而不是{ {1}}或词法范围(使用编译指示或say块)。

答案 1 :(得分:11)

您可以创建一个角色来执行此操作。一个简单的版本是:

role KeyRequired { 
    method AT-KEY( \key ) { 
        die "Key {key} not found" unless self.EXISTS-KEY(key); 
        nextsame; 
    } 
};

然后使用my %key does KeyRequired;创建哈希,如果您请求不存在的密钥,它将失效。

答案 2 :(得分:9)

在这种情况下,Perl 5警告而不是死亡。如果使用等效代码,Perl 6将执行相同的操作:

my %key;
print "%key<fake_key>\n"; # Gives a warning

或更简洁地使用put

my %key;
put %key<fake_key>;

put例程(“使用终止符打印”)将对值进行字符串化,这将触发有关在字符串上下文中使用未定义值的警告。

与之相反,say不进行字符串化,而是在对象上调用.gist,并打印返回的任何内容。对于未定义的值,其要点是其类型的名称,并用括号括起来。通常,say-在下面使用.gist-提供更多信息。例如,考虑一个数组:

my @a = 1..5;
put @a;          # 1 2 3 4 5
say @a;          # [1 2 3 4 5]

put仅将元素与空格连接在一起,而say代表结构,它是一个数组。

答案 3 :(得分:9)

简单的答案是不使用say

say %key<fake_key>;
# (Any)

put %key<fake_key>;
# Use of uninitialized value of type Any in string context.
# Methods .^name, .perl, .gist, or .say can be used to stringify it to something
# meaningful.
#   in block <unit> at <unknown file> line 1

say调用.gist可以打印出足够多的信息,供人类理解所打印的内容。
put只是尝试将其变成Str并打印出来,但是在这种情况下会产生错误。