Главная > Perl > День 8: расчесываем ограничения

День 8: расчесываем ограничения

Перевод на русский язык восьмой статьи цикла Perl 6 Advent Calendar.

Мы попали в точку, где предыдущие подарки будут полезны для нынешних. Сегодня у нас двойной набор: метод comb (расческа) и идея ограничений.

Аналогично статичным типам предыдущих определений, ограничения позволяют качественнее управлять написанием подпрограмм и методов. Во многих других языках программирования вы должны передавать параметры в подпрограмму, а затем проверять введенные данные. С ограничениями вы можете проверять правильность непосредственно в объявлении.

Возьмем простой пример. Если целое число четное, то я не хочу иметь дела с этой подпрограммой. В Perl 5 вы бы написали что-то похожее на это:

sub very_odd
{
    my $odd = shift;
    unless ($odd % 2)
    {
        return undef;
    }
    # Process the odd number here.
}

В Perl 6 это может быть упрощено:

sub very_odd(Int $odd where {$odd % 2})
{
    # Process the odd number here
}

При попытке вызова very_odd с четным числом вы получите сообщение об ошибке. Не волнуйтесь, хотя вы можете использовать возможности мультифункций чтобы дать даже числам возможность проявить себя… может быть. ;)

multi sub very_odd(Int $odd where {$odd % 2})
{
    # Process the odd number here
}
multi sub very_odd(Int $odd) { return Bool::False; }

Эти ограничения могут быть полезны при сочетании с методом .comb. Что же такое .comb? Для тех, кто расчесывает свои волосы: вы обычно пользуетесь расческой, чтобы уложить отдельные волоски. Для тех, кто любит использовать .split все как раз наоборот. Этот простой фрагмент кода должен продемонстрировать как работает .comb:

say "Perl 6 Advent".comb(/<alpha>/).join('|');
say "Perl 6 Advent".comb(/<alpha>+/).join('|');

Регулярные выражения, скорее всего, будут открыты в другой день, но быстрый взгляд не будет болезненным. Первая строка будет выводить «P|e|r|l|A|d|v|e|n|t»: берется каждый буквенный символ и помещается во временный массив. Затем он соединяется с символом вертикальной черты. Вторая строка аналогична, только она захватывает столько букв, сколько сможет, отсюда результат «Perl|Advent».

Однако, сила .comb намного больше. После того как вы «расчесали» что хотели, вы можете управлять «волосками». Если у вас есть определенный набор шестнадцатеричных ASCII символов, вы можете использовать гипероператоры для преобразования каждого кусочка в ASCII эквивалент!

say "5065726C36".comb(/<xdigit>**2/)».fmt("0x%s")».chr
# Outputs "Perl6"

Помните, это Perl. Существует много способов сделать это. ☺

Со всеми подарками, что были представлены сегодня, я дам вам задачу. С помощью Kayl Hasselbacher, я смог сделать достойную версию древнего шифра Цезаря при помощи ограничений, .comb, и старого доброго .map:

use v6;

sub rotate_one( Str $c where { $c.chars == 1 }, Int $n ) {
    return $c if $c !~~ /<alpha>/;
    my $out = $c.ord + $n;
    $out -= 26 if $out > ($c eq $c.uc ?? 'Z'.ord !! 'z'.ord);
    return $out.chr;
}

sub rotate(Str $s where {$s.chars}, Int $n = 3)
{
    return ($s.comb.map: { rotate_one( $_, $n % 26 ) }).join( '' );
}

die "Usage:\n$*PROGRAM_NAME string number_for_rotations" unless @*ARGS == 2;

my Str $mess = @*ARGS[0];
my Int $rotate = @*ARGS[1].Int;

say qq|"$mess" rotated $rotate characters gives "{rotate($mess,$rotate)}".|;

Я хотел бы посмотреть как остальные смогут реализовать код этого алгоритма используя Perl 6 и уже открытые подарки. В конце концов язык может получиться только лучше и удобнее.

© Оригинальная статья.

VN:F [1.9.22_1171]
Rating: 8.0/10 (4 votes cast)
День 8: расчесываем ограничения, 8.0 out of 10 based on 4 ratings
Categories: Perl Tags:
  1. 23 Июнь 2010 в 13:31 | #1
    Использует Firefox 3.6.3 Firefox 3.6.3 на FreeBSD FreeBSD

    Зачем писать так длинно?

    unless ($odd % 2)
    {
    return undef;
    }

    Можно ж короче:

    return undef unless $odd % 2;

    VN:F [1.9.22_1171]
    Rating: 5.0/5 (1 vote cast)
    • 24 Июнь 2010 в 09:48 | #2
      Использует Google Chrome 6.0.437.3 Google Chrome 6.0.437.3 на GNU/Linux GNU/Linux

      Ваш вариант стал не короче, а более трудным для восприятия. Именно за такие записи многие и не любят Perl.

      VN:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
  2. Володин
    25 Сентябрь 2011 в 20:53 | #3
    Использует Google Chrome 14.0.835.186 Google Chrome 14.0.835.186 на Windows XP Windows XP

    @Ky6uk

    этот вариант не стал более трудным для восприятия,
    но речь шла о том, что «ограничения позволяют качественнее управлять написанием подпрограмм и методов.», и соответственно для примера и простоты восприятия продемонстрировали маленькую подпрограмму.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
  1. Пока что нет уведомлений.