Поддерживает ли Perl6 что-то эквивалентное разделам Perl5 __DATA__ и __END__?

Есть ли в perl6/Rakudo что-то эквивалентное perl5? __DATA__ или же __END__ разделы?

4 ответа

Решение

Цитата S26:

Именованные блоки Perldoc с типом DATA являются эквивалентом Perl 6 для Perl 5. __DATA__ раздел. Разница в том, что =DATA-блоки - это просто обычные блоки Pod и могут появляться в любом месте исходного файла и столько раз, сколько требуется. Краткий обзор 2 описывает новый интерфейс Perl 6 для встроенных данных.

Теоретически вы должны иметь возможность сделать что-то вроде этого (кто-то, пожалуйста, исправьте синтаксис, если он выключен):

use v6;

=begin DATA
Foo
=end DATA

say @=DATA;

На практике кажется, что Ракудо пока не поддерживает это.

Чтобы тщательно выборочно процитировать текущий проектный документ S02:

Больше нет никакого специального потока данных - любой блок Pod в текущем файле может быть доступен через объект Pod...

Вы должны разбить содержимое [Pod block] на строки самостоятельно.

[Спекулятивно] Также возможно обрабатывать объект Pod как IO::Handle, чтобы построчно считывать информацию Pod (как дескриптор файла DATA в Perl 5, но для любого блока Pod).

Таким образом, вместо одного раздела DATA для каждого файла, к которому вы обращаетесь, читая дескриптор файла, вы определяете любое количество блоков Pod в своем файле сценария; они хранятся в $=pod переменная во время компиляции; вы читаете из этой переменной; и те, что называются "данными", являются эквивалентами данных Perl 5.

Это работает сегодня. Я покажу это через мгновение. Но сначала мне нужно поговорить о вещах, которые сегодня не работают.

Цитата выше была очень избирательной. Подчеркнутый текст говорит о том, что P6 автоматически создает переменную с именем формы $=foo соответствующие блокам Pod с именем 'foo'. Это общая, до сих пор не реализованная особенность блоков Pod, а не только блоков данных.

В разделе "Блок данных" документа S26 по разработке Pod рассказывается о том, что блоки данных делают более причудливые вещи, чем простые старые блоки Pod. Это еще не было реализовано.

Итак, теперь давайте перейдем к тому, что можно сделать сегодня:

=foo This is a Pod block. A single line one. This Pod block's name is 'foo'.

=begin qux
This is another syntax for defining a Pod block.
It allows for multi line content.
This block's name is 'qux'.
=end qux

=data A data block -- a Pod block with the name 'data'.

# Data blocks are P6's version of P5's __DATA__.
# But you can have multiple data blocks:

=begin data
Another data block.
This time a multi line one.
=end data

$=pod.grep(*.name eq 'data').map(*.contents[0].contents.say);

Это печатает:

A data block -- a Pod block with the name 'data'.
Another data block. This time a multi line one.

Итак, это работает. Но для этого явно нужно намного больше сахара.

Кстати, если последняя строка стиля FP не имеет смысла, вот императивный эквивалент:

for @$=pod {
  if .name eq 'data' {
    say .contents[0].contents
  }
};

В качестве обходного пути до полной реализации вы можете использовать heredocs.

for data().lines -> $line {
    put $line;
}

sub data {
    return q:to/END/;
           Foo, bar, baz
           1, 2, 3
           END
}

Выходы

Foo, bar, baz
1, 2, 3

Чтобы получить массив данных, поместив данные в конец программы, чтобы улучшить читаемость, вот вариант ответа @Christopher Bottoms:

my @txts = data();
dd @txts;
# this works too
my %stuff = hashdata();
dd %stuff;

# a lot of lines

sub data() {
    return ( q:to/LINE1/,
        Phasellus dictum, nunc id vestibulum rhoncus, mauris massa tempus nibh, 
        nec tincidunt nisi tellus et arcu. Phasellus vulputate consectetur
        vulputate. Quisque viverra commodo velit ac tincidunt. Nulla et est sem.
        Mauris gravida, nulla rutrum pharetra dapibus, eros velit feugiat nibh,
        nec iaculis purus urna ut diam. Praesent molestie felis a turpis gravida
        placerat. Duis sagittis pulvinar risus non aliquet. Nunc quis purus
        tempor, mattis nunc eu, porta ligula. Suspendisse dictum sit amet urna
        dapibus suscipit.  
        LINE1  
        q:to/LINE2/,  
        Praesent molestie felis a turpis gravida
        placerat. Duis sagittis pulvinar risus non aliquet. Nunc quis purus
        tempor, mattis nunc eu, porta ligula. Suspendisse dictum sit amet urna
        dapibus suscipit.
        LINE2
        q:to/LINE3/);
        Quisque viverra commodo velit ac tincidunt. Nulla et est sem.
        Mauris gravida, nulla rutrum pharetra dapibus, eros velit feugiat nibh,
        nec iaculis purus urna ut diam. Praesent molestie felis a turpis gravida
        placerat.
        LINE3
}

sub hashdata() { # a hash works too.
      return ( 'p' => q:to/PDATA/,
        Some multiline data
        in some lines
        PDATA

        'q' => q:to/QDATA/,
           More data in 
           multiple lines
           QDATA

         'r' => q:to/RDATA/
              Note that indentation depends on the position of the 
              ending token.
              Also, the punctuation following the regex is the punctuation
              following the expression. So a comma after each of the 
              p and q, but not needed after the r
              RDATA
         )
}
Другие вопросы по тегам