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
)
}
YES.
According to this 2023 perl6.users email conversation, you end your program/document with:
=finish
Then: "Anything after =finish
is put in string that can be pulled into a Raku program with $=finish
(also undocumented)."
So you can reference the string (within the body of your program) using:
$=finish
That link further elaborates:
"
=finish
was introduced instead of Perl's__DATA__
.""
=finish
is an undocumented part of the POD6 specification ... . It will be documented soon."
https://www.nntp.perl.org/group/perl.perl6.users/2023/06/msg10997.html
© 2022 - 2024 — McMap. All rights reserved.