Как заставить perl6 умереть на неопределенных значениях? - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь работать с хэшем в 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

Как я могу получить эквивалент use warnings 'FATAL' => 'all' и use autodie qw(:all) в Perl6?

Ответы [ 4 ]

0 голосов
/ 22 января 2019

Aiui ваш вопрос:

Я ищу use autodie qw(:all) & use warnings 'FATAL' => 'all' в Perl6

Эквивалент autodie в P6

Aiui use autodie qw(:all) в P5 становится use fatal; в P6. Это лексически ограниченный эффект.

Раздел autodie в руководстве по скорлупе от P5 к P6 объясняет, что процедуры теперь возвращают Failure с, чтобы указать на ошибки.

Прагма fatal позволяет возвращать Failure из подпрограммы, автоматически генерирует исключение, содержащее Failure. Если вы не предоставите код, который их перехватит, эти исключения, включающие Failure s, автоматически исчезнут.

Эквивалент use warnings 'FATAL' в P6

Aiui use warnings 'FATAL' => 'all' в P5 становится CONTROL { when CX::Warn { note $_; exit 1 } } в P6. Это эффект лексической области действия.

CONTROL исключения объясняет, как они работают.

CONTROL исключения - это подмножество всех исключений, которые .resume 'd по умолчанию - программа остается в живых по умолчанию, когда они выбрасываются.

Код P6, который я предоставил (который взят из Как я могу сделать все предупреждения фатальными? , на который вы ссылались), вместо этого CONTROL исключений умирает (из-за exit рутина).

Возвращаясь к вашему текущему вопросу:

say %key<fake_key>; # (Any)

Я хочу, чтобы программа умерла в таких случаях ...

Используйте либо ответ Jonathan ++ (используйте put, который, в отличие от say, не пытается сохранить вашу программу живым), либо ответ KeyRequired Scimon ++, который сделает доступ к несуществующему ключу фатальным.

... как это делает Perl5 ...

Только если вы используете use warnings 'FATAL' ..., так же, как P6, если вы используете эквивалент.

... потому что это означает, что важные данные отсутствуют.

Часто это означает, что неважные данные отсутствуют, или даже важные данные, которые вы не хотите, определяли в течение некоторого времени, когда вы пытаетесь получить к нему доступ, поэтому Perls по умолчанию поддерживает вашу программу живой и требует, чтобы вы сообщали ей, что хотите, если Вы хотите что-то другое.

Вы можете использовать вышеупомянутые конструкции, чтобы получить точный желаемый результат, и они будут ограничены определенной переменной (если вы используете роль KeyRequired) или оператором (используя put вместо say) или лексическая область (с использованием прагмы или блока CONTROL).

0 голосов
/ 22 января 2019

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 представляет структуру и что это массив.

0 голосов
/ 22 января 2019

Простой ответ - не использовать 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 и распечатать, но в этом случае выдает ошибку.

0 голосов
/ 22 января 2019

Вы можете создать роль для этого.Простая версия будет выглядеть так:

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

Затем вы создадите свой хеш с помощью: my %key does KeyRequired;, и он умрет, если вы запросите несуществующий ключ.

...