Завершен перевод документа  Differences Between Perl 5 and Perl 6

Данный пост является вырезкой из документации Perl6::Perl5::Differences


Встроенные функции

Некоторые встроенные функции удалены. Дополнительно см. [S29]: Устаревшие функции

Ссылки в прошлом (или все типы данных являются ссылками)

В Perl 6 захват объектов заполнил экологическую нишу ссылок. Можно представить себе, что это "толстые" ссылки, то есть ссылки, которые могут захватывать не только текущую идентичность одного объекта, но так же относительные идентичности нескольких связанных объектов. С другой стороны, можно считать, что ссылки в Perl 5 являются частной формой захвата, когда создается ссылка только на один элемент.

  Было:  ref $foo eq 'HASH'
  Стало: $foo ~~ Hash

  Было:  @new = (ref $old eq 'ARRAY' ) ? @$old : ($old);
  Стало: @new = @$old;

  Было:  %h = ( k => \@a );
  Стало: %h = ( k => @a );

Передача аргумента по ссылке с последующей его модификацией:

  Было:  sub foo {...};        foo(\$bar)
  Стало: sub foo ($bar is rw); foo($bar)

В вышеприведенных примерах "устаревших" ссылок имеются некоторые нюансы. Подробнее о захватах можно узнать в документе [S02]: Имена и переменные , или на странице Perl6::FAQ::Capture.

say()

Это та же функция print с автоматическим добавлением символа новой строки:

    Было:     print "Hello, world!\n";
    Стало:    say   "Hello, world!";

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

wantarray()

Функции wantarray() в Perl 6 нет. Контекст подпрограммы определяется за её пределами, это значит, что подпрограмма "не знает", в каком контексте она выполняется.

Вместо этого нужно возвращать объекты, которые действуют в зависимости от своего контекста. Подробнее см. [S06]: Функция want 

Данный пост является вырезкой из документации Perl6::Perl5::Differences


Перегрузка

Как встроенные функции, так и операторы являются перегружаемыми подпрограммами и методами [ или мультиподпрограммами и мультиметодами от анг. multi subs and methods], изменение их поведения к определенному типу решается добавлением соответствующих мультиподпрограмм и мультиметодов. Если вы желаете, чтобы данные подпрограммы были доступны глобально, то их нужно установить в область видимости GLOBAL:

multi sub GLOBAL::uc(RussianStr $str, Int $i) { ... }

# "перегрузка" оператора объединения строк:
multi sub infix:<~>(Str $us, RussianStr $them) { ... }

Чтобы осуществить приведение типа (т.е значение одного типа преобразовать в другому), можно просто создать метод с именем типа данных, к которому нужно привести значение.

sub needs_bar(Bar $x) { ... }
class Foo {
    ...
# приведение к типу Bar: method Bar { ... } }

needs_bar(Foo.new); # передача подпрограмме объекта типа Bar

Cемантика списка и хэша

Для того, чтобы написать класс, чьи объекты могут быть отнесены к переменным с сигилом @, нужно реализовать позиционные роли. Аналогично для сигила % нужно реализовать ассоциативную роль. Сигил & подразумевает фрагмент кода, который может быть вызван.

Роли обеспечиваются операторами postcircumfix:<[ ]> ( позиционный, для индексировании массива), postcircumfix: <{ }> (ассоциативный) и postcircumfix:<()> (вызываемый фрагмент кода). Технически это обычные методы с причудливым синтаксисом. Нужно только подкорректировать их для выражения соответствующей семантики.

class OrderedHash does Associative {
    method postcircumfix:<{}>(Int $index) {
        # здесь код, оперирующий отдельными элементами хэша
    }
    method postcircumfix:<{}>(**@slice) {
        # здесь код, оперирующий срезами хэша
    }
    ...
}

my %orderedHash = OrderedHash.new();
say %orderedHash{'a'};

См. подробнее в спецификации [S13]

Изменения в семантике операторов тестирования файлов

Было:    if (-r $file && -x _) { ... } 
Стало:   if $file ~~ :r & :x  { ... }

Операторы тестирования файлов теперь возвращают в качестве результата булево значение. Детальнее об этом см. [S03]: Изменения в операторах Perl

Сегодня перевел очередной кусочек спецификации Perl6::Perl5::Differences, а именно ту часть, в которой описывается объектно-ориентированное программирование на perl 6.


Perl6::Perl5::Differences - Отличия между Perl 5 и Perl 6

Объекты

В Perl 6 реализована полноценная объектная модель, с ключевыми словами для классов, объектов и атрибутов. Имена публичных атрибутов предваряются символом ., а имена приватных атрибутов - символом !. (В дальнейшем будем их называть твигилы (анг. twigil) (Прим. перев.) )

class YourClass {
    has $!private;
    has @.public;
    
    # с указанием права доступа "чтение-запись"
    has $.stuff is rw;
    
    method do_something {
        if self.can('bark') {
            say "Something doggy";
        }
    }
}

Вызовы метода обозначаются символом . вместо ->

    Было:     $object->method 
    Стало:    $object.method

Отличие символических ссылок от жестких при вызове динамического метода

    Было:   $self->$method()
    Стало:  $self.$method()   # жесткая ссылка
    Стало:  $self."$method"() # символическая ссылка
Продолжение следует ...

Сегодня перевел очередной кусочек спецификации Perl6::Perl5::Differences.


Perl6::Perl5::Differences - Отличия между Perl 5 и Perl 6

Блоки и Операторы

См. S04 если хотите узнать больше об операторах и блоках в Perl 6.

Не требуются скобки в управляющих структурах

    Раньше:    if ($a < $b) { ... }
    Теперь:    if  $a < $b  { ... }

Аналогично для while, for, и.т.д. Можно использовать скобки, но при этом придется соблюдать, чтобы был пробел после if, иначе это будет вызовом подпрограммы.

Теперь try {} вместо eval {}.

Теперь вместо блока eval используется try.

    Было:  
          eval { 
            ... 
          }; 
          if ($@) { 
            warn "ошибка: $@";
          } 
    Стало: 
          try  {
             # ...
             CATCH { warn "ошибка: $!" }
          }

CATCH обеспечивает больше гибкости в обработке ошибок. См. [S04]: "Обработчики исключений" для получения детальной информации.

foreach становится for

    Раньше:    foreach (@whatever) { ... }
    Теперь:    for @whatever       { ... }

Кроме того, изменился способ присвоения нечто другому, чем $_:

    Было:    foreach my $x (@whatever) { ... }
    Стало:   for @whatever -> $x       { ... }

Подобным образом можно извлекать несколько элементов одновременно:

    Было:     while (my($age$sex$location) = splice @whatever, 0, 3) { ... }
    Стало:    for @whatever -> $age, $sex, $location { ... }

(За исключением того, что версия for не уничтожает массив)

В спецификациях [S04]: "Оператор for" и [S29]: each об этом говорится подробнее.

for становится loop

    Было:     for ($i = 0; $i < 10$i++) { ... }
    Стало:    loop ($i = 0; $i < 10; $i++) { ... }

Также loop можно использовать для создания бесконечных циклов:

    Было:     while (1) { ... }
    Стало:    loop { ... }

Регулярные выражения и "правила"

В примере ниже иллюстрируется простая трансляция регулярного выражения Perl5 в Perl6:

    Было:     $str =~ m/^\d{2,5}\s/i
    Стало:    $str ~~ m:P5:i/^\d{2,5}\s/

Здесь используется модификатор :P5. Так как стандартный синтаксис Perl6 достаточно разнообразный, 'P5' отмечает где необходима совместимость с синтаксисом Perl5. Для замены:

    Было:     $str =~ s/(a)/$1/e;
    Стало:    $str ~~ s:P5/(a)/{$0}/;

Обратите внимание, что первый буфер захвата не $1, как было раньше, а $0, а модификатор /e удален в пользу встроенной закрытой нотации.

Данная тема подробно рассматривается в спецификации S05. См. также:

Связанный с ним Апокалипсис (анг. Apocalypse), в котором объясняются изменения:

  http://dev.perl.org/perl6/doc/design/apo/A05.html

И связанная с ним Экзегеза (анг. Exegesis), где данная тема объясняется более детально:

  http://dev.perl.org/perl6/doc/design/exe/E05.html
Продолжение следует ...

Привет, сегодня продолжаю перевод документа Perl6::Perl5::Differences.


Perl6::Perl5::Differences - Отличия между Perl 5 и Perl 6

Операторы

Полный список операторов задокументирован на страницах [S03]: "Изменения синтаксиса операторов Perl 5" и [S03]: "Новые операторы".

Некоторые ключевые аспекты:

Новая форма интерполяции оператора кавычек qw()

    Было:    qw(foo)
    Стало:   <foo>

    Было:    ("foo", (split ' '$bar), "bat")
    Стало:   <<foo $bar bat>>

Операторы кавычек теперь имеют модификаторы, которые могут быть использованы для изменения их интерпретации ( подобно модификаторам регулярных выражений в Perl 5), с их помощью можно даже определить свои собственные операторы кавычек.

Обратите внимание, что подпись () теперь является вызовом подпрограммы, таким образом вместо qw(a b) надо написать qw<a b> или qw[a b] (если вам не симпатична простая запись <a b>).

Другие важные изменения в операторах

Объединение строк теперь осуществляется символом ~.

Сопоставление регулярному выражению производится оператором "умного сопоставления" - ~~, Perl 5 оператор сопоставления =~ больше не используется.

    if "abc" ~~ m/a/ { ... }

| и & как инфиксные операторы теперь объединяют конструкции. Операторы бинарный AND и бинарный OR разделены на строковые и числовые, то есть ~& - бинарный строковый AND, +& бинарный числовой AND, ~| - бинарный строковый OR и.т.д.

	Было:  $foo & 1;
	Стало: $foo +& 1;

Побитовые операторы в настоящее время с префиксом +, ~ или ? в зависимости от типа данных: число, строка или логическое значение.

	Было:  $foo << 42;
	Стало: $foo +< 42;

Операторы присваивания изменены таким же образом:

	Было:  $foo <<= 42;
	Стало: $foo +<= 42;

Скобки не создают списки, они просто группируют. Списки формируются оператором запятой. У неё приоритет выше, чем у оператора присвоения списка, это позволяет с правой стороны указывать список без скобок.

    my @list = 1, 2, 3;     # В @list на самом деле 3 элемента

Оператор стрелка -> для разыменовывания больше не используется. Так как все является объектом, а разыменовывающие скобки - это просто вызовы метода с синтаксическим сахаром, можно сразу использовать соответствующую пару скобок для индексирования либо вызова метода:

    my $aoa = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    say $aoa[1][0];         # 4

    my $s = sub { say "hi" };
    $s();
    # или
    $s.();
    $lol.[1][0]

Ну вот, наконец-то вышел первый официальный выпуск компилятора Perl 6 Rakudo - это радует, так теперь появилась определенная уверенность в завтрашнем дне Perl 6 !

На позитивной ноте начинаю перевод официальной документации Perl 6. Итак, первым делом рассмотрим документ Perl6::Perl5::Differences в котором описываются отличия между пятой и шестой версиями Perl:


Perl6::Perl5::Differences - Отличия между Perl 5 и Perl 6

Данный документ предназначен для тех программистов, которые знают Perl 5, но не знают Perl 6 и интересуются их основными отличиями. Подробнее об отличиях рассказывается в справочном пособии Perl 6.

Документ в настоящее время описывает не все отличия в Perl 5 и Perl 6, со временем это будет исправлено.

Всякая всячина

Сигилы

Там, где раньше говорили:

    my @fruits = ("яблоко""груша""банан");
    print $fruit[0], "\n";

Вы бы сейчас сказали:

    my @fruits = "яблоко", "груша", "банан";
    say @fruit[0];

Или даже используюя оператор <>, который заменяет qw():

    my @fruits = <яблоко груша банан>;

Обратите внимание, что теперь, когда мы хотим извлечь элемент, указываем сигил @ вместо $. Возможно правильнее рассуждать так: сигил переменной теперь является частью его имени, поэтому он ни в каком случае не изменяется.

То же самое относится и к хэшам:

    say "В этом году в феврале %days{'February'} дней"

Опять же, в сокращенной форме:

    say "В этом году в феврале %days<February> дней"

Подробнее обо всем этом вы можете узнать из документа [S02]: "Имена и переменные".

Имена глобальных переменных предваряются твигилом

Да, твигил. Это второй символ в имени переменной. Для глобальных переменных таковым является *.

    Было:     $ENV{FOO}
    Стало:    %*ENV<FOO>

Детальнее см. [S02]"Имена и переменные".

Новые способы ссылаться на элементы массивов и хэшей

Количество элементов в массиве:

    Было:    $#array+1 or scalar(@array)
    Стало:   @array.elems

Индекс последнего элемента массива:

    Было:    $#array
    Стало:   @array.end

Таким образом, последний элемент массива:

    Было:    $array[$#array]
    Стало:   @array[@array.end]
             @array[*-1]              # beware of the "whatever"-star

Подробнее об этом см. "[S02]: "Встроенные типы данных".

Удалены удвоенные символы подчеркивания ключевых слов

    в Perl 5            в Perl 6
    ---                 ---
    __LINE__            $?LINE
    __FILE__            $?FILE
    __PACKAGE__         $?PACKAGE
    __END__             =begin END
    __DATA__            =begin DATA

См. "[S02]: Удвоенные символы подчеркивания остались в прошлом" для получения детальной информации. В примере выше используется твигил ? - он ссылается на данные, которые известны во время компиляции.

Контекст

Есть еще три основных контекста - void, item (прежний скалярный тип) и списковый(list). Имеются дополнительные более специализированные контексты и операторы, принуждающие к определенному контексту.

    my @array = 1, 2, 3;

    # общий контекст элемента
    my $a = @array; say $a.WHAT;    # печатает Array

    # строковый контекст
    say ~@array;                    # "1 2 3"

    # числовой контекст
    say +@array;                    # 3

    # логический(boolean) контекст
    my $is-nonempty = ?@array;

Символы ' и - можно использовать в рамках идентификаторов, если они находятся между двумя буквенными символами.