문제

Does perl6/Rakudo have something equivalent to perl5's __DATA__ or __END__ sections?

도움이 되었습니까?

해결책

Quote S26:

Named Perldoc blocks whose typename is DATA are the Perl 6 equivalent of the Perl 5 __DATA__ section. The difference is that =DATA blocks are just regular Pod blocks and may appear anywhere within a source file, and as many times as required. Synopsis 2 describes the new Perl 6 interface for inline data.

In theory you should be able to do something like this (somebody please fix the syntax if it’s off):

use v6;

=begin DATA
Foo
=end DATA

say @=DATA;

In practice it seems that Rakudo does not support that, yet.

다른 팁

To carefully selectively quote the current S02 design document:

There is no longer any special DATA stream--any Pod block in the current file can be accessed via a Pod object ...

You have to split [Pod block] contents into lines yourself.

[Speculative] It may also be possible to treat a Pod object as an IO::Handle, to read the Pod information line-by-line (like the DATA filehandle in Perl 5, but for any Pod block).

So, instead of the single DATA section per file which you access by reading a filehandle, you define any number of Pod blocks in your script file; they're stored in the $=pod variable at compile time; you read from that variable; and the ones called 'data' are the equivalents of Perl 5's DATA.

This works today. I'll show that in a moment. But first I need to talk about stuff that does not work today.

The quoting above was highly selective. The elided text talked about P6 automatically creating a variable with a name of the form $=foo corresponding to Pod blocks with the name 'foo'. This is a general still unimplemented feature of Pod blocks, not just data blocks.

The "data block" section of the Pod design doc S26 talks about data blocks doing some fancier stuff than plain old Pod blocks. This has not yet been implemented either.

So, now let's move on to what can be done today:

=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);

This prints:

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

So, it sorta works. But it clearly needs a lot more sugar.

By the way, if the last FP style line didn't make sense, here's an imperative equivalent:

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

As a work-around until this gets fully implemented, you can use heredocs.

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

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

Outputs

Foo, bar, baz
1, 2, 3

To get an array of data, while putting the data at the bottom of the program to help with readability, here is an variation of @Christopher Bottoms answer:

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
         )
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top