Perl6(又名 Raku)是否支持与 Perl5 的 __DATA__ 和 __END__ 部分等效的内容?

发布于 2024-10-04 09:36:16 字数 86 浏览 9 评论 0原文

perl6/Rakudo 是否有与 perl5 的 __DATA____END__ 部分等效的内容?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

慕烟庭风 2024-10-11 09:36:16

引用 S26

命名 Perldoc 块,其类型名为
DATA 是 Perl 6 的等价物
Perl 5 __DATA__ 部分。这
区别在于 =DATA 块是
只是普通的 Pod 块,可能会出现
源文件中的任何位置,以及
根据需要多次。 概要 2
描述了新的 Perl 6 接口
内联数据。

理论上你应该能够做这样的事情(如果语法关闭,请有人修复语法):

use v6;

=begin DATA
Foo
=end DATA

say @=DATA;

实践中Rakudo 似乎还不支持这一点。

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.

遗失的美好 2024-10-11 09:36:16

要仔细选择性地引用当前的 S02 设计文档:

不再有任何特殊的数据流——任何 Pod 块
可以通过 Pod 对象访问当前文件...

您必须自己将 [Pod block] 内容拆分成行。

[推测]也可以将 Pod 对象视为
IO::Handle,逐行读取Pod信息(如DATA
Perl 5 中的文件句柄,但适用于任何 Pod 块)。

因此,您可以在脚本文件中定义任意数量的 Pod 块,而不是通过读取文件句柄来访问每个文件的单个 DATA 部分;它们在编译时存储在 $=pod 变量中;你从该变量中读取;所谓的“data”相当于 Perl 5 的 DATA

这在今天有效。我稍后会展示这一点。但首先我需要谈谈今天不起作用的东西。

上面的引用是高度选择性的。省略的文本谈到 P6 自动创建一个名称为 $=foo 形式的变量,对应于名称为“foo”的 Pod 块。这是 Pod 块的一个尚未实现的通用功能,而不仅仅是数据块。

Pod 设计文档 S26 的“数据块”部分讨论了数据块做一些更奇特的事情比普通的旧 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
  }
};

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
  }
};
岁月流歌 2024-10-11 09:36:16

作为完全实现之前的解决方法,您可以使用此处文档。

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

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
陈甜 2024-10-11 09:36:16

要获取数据数组,同时将数据放在程序底部以帮助提高可读性,这里是 @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
         )
}

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
         )
}
情场扛把子 2024-10-11 09:36:16

是。

根据此2023 perl6.users 电子邮件对话,您以以下方式结束程序/文档:

=finish

然后:“将 =finish 之后的任何内容放入可以使用 $=finish (也未记录)将其拉入 Raku 程序的字符串。

因此,您可以使用以下方式引用该字符串(在程序主体内):

$ =finish


该链接进一步阐述:

  1. “引入了=finish,而不是 Perl 的 __DATA__。”

  2. =finish 是一个POD6 规范中未记录的部分......很快就会记录下来。”


https://www.nntp.perl.org/group/perl.perl6.users/2023/06/ msg10997.html

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:

  1. "=finish was introduced instead of Perl's __DATA__."

  2. "=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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文