【问题标题】:Multidimensional Hash Elements in Perl6Perl6 中的多维散列元素
【发布时间】:2023-04-11 05:45:01
【问题描述】:

我正在尝试在 Perl6 中分配散列变量,就像在 Perl 中一样。当我阅读一个文件时,我接受某些元素并分配给一个哈希:

%key<$barcode><$position> = $sample-id

这在 Perl5 中的位置

$key{$barcode}{$position} = $sample_id

这样做后我可以打印散列分配,所以我认为分配有效。

当我用

打印这个哈希时
say %key.perl;

这只给了

{"\$barcode" => ${"\$position" => "ZZ12345"}}

如何打印出像 Perl5 的 Data::DumperDDP https://metacpan.org/pod/Data::Printer 这样的多维散列,因为 say %key.perl 似乎不适用于多维散列?

【问题讨论】:

  • say %key.perl 在什么意义上不起作用? my %h = a =&gt; { b =&gt; { c =&gt; 42 } }; say %h 似乎输出 {a =&gt; {b =&gt; {c =&gt; 42}}} 对我来说很好。

标签: hash raku


【解决方案1】:

&lt;&gt; 与 perl5 中的 {''} 相同,因此只能用于字符串键。如果您想使用变量名,请使用:

%key{$barcode}{$position} = $sample_id 这应该可以解决问题。

您还可以使用双尖括号选项来进行字符串插值。

%key&lt;&lt;$barcode&gt;&gt;&lt;&lt;$position&gt;&gt; = $sample_id

【讨论】:

  • 我通常建议不要使用 &lt;&lt;...&gt;&gt; 进行插值,因为它将空格视为分隔符。考虑:perl6 -e 'my $key = "1 2 3"; my %hash = $key =&gt; 42; say %hash&lt;&lt;$key&gt;&gt;
  • 是的……但我觉得我应该提到它们。你可能是对的。
【解决方案2】:

您误解了 Perl 6 语言。 (这是可以理解的,不是第一次)

以下是您尝试使用的功能的简要历史课程。


在 Perl 5 中,如果 {} 之间的唯一内容是空词,则不必引用密钥。

use v5.12;

my %hash;
$hash{fubar} = 'abc';
# $hash{'fubar'} = 'abc';

say qq'"@{[ $hash{fubar} ]}"';
# "abc"

这是一个特例,Perl 6 设计的目标之一是尽可能少地包含特例。因此,以下内容在 Perl 6 中不起作用。

use v6.d;

my %hash;
%hash{fubar} = 'abc';
# %hash{ fubar() } = 'abc';

say qq'"%hash{fubar}"';
# say qq'"%hash{ fubar() }"';
===SORRY!=== Error while compiling ./test.p6
Undeclared routine:
    fubar used at lines 4, 7

这个错误意味着它甚至无法编译。


在两种 Perl 语言中都有一个引用单词的功能。

use v5;
my @array = qw< a b c d >;
use v6;
my @array = qw< a b c d >;

在 Perl 6 中可以缩短为

use v6;
my @array =   < a b c d >;

qw 在 Perl 6 中实际上是 Q :q :w / Q :single :words 的缩写。它启用单引号行为并启用拆分为单词。 (按空格分割)
&lt;&gt; 有效,因为那里不需要中缀运算符 &lt;。)

为了弥补{}之间的自动裸词引用没有被复制,添加了后缀&lt;&gt;。它结合了qw{} 的特性。

use v6;
my %hash;

%hash{qw< foo bar baz >};
%hash{  < foo bar baz >};
%hash<    foo bar baz >;  # <---

Perl 6 中还有一个更高级的引号功能

use v6;
my $a = 'a b "c d"';

say qqww<< $a e f 'g h ' '$a'>>.perl;
say     << $a e f 'g h ' '$a'>>.perl;
say     «  $a e f 'g h ' '$a' ».perl;
# All 3 are exactly equivalent
# ("a", "b", "c d", "e", "f", "g h ", "\$a")

qqwwQ :qq :ww / Q :double :quotewords 的缩写。即启用双引号行为并启用引号分词。

:double 是启用 $a 插值的原因。
:quotewords 拆分空格上的单词,但也允许引号控制拆分的位置。
(注意:quotewords 发生在最后)

qqwqww 也可以,但没有缩短的写法。)

还有一个后缀&lt;&lt;&gt;&gt;/«»

use v6;
my %hash;
my $a = 'a b "c d "';

%hash{<< $a e f 'g h ' '$a' >>};
%hash<<  $a e f 'g h ' '$a' >>;
%hash«   $a e f 'g h ' '$a'  »;

# All 3 are exactly equivalent to
%hash{'a', 'b', 'c d ', 'e', 'f', 'g h ', '$a'};
#               ^^^^^^            ^^^^^^

这种方式使得后缀&lt;&gt; 不是一个特殊情况。


很多示例使用 %hash&lt;fubar&gt; 的原因是它是惯用的 Perl 6。
也许它应该被视为文档中的一个更高级的功能并且减少了使用,因为到目前为止你不是第一个犯这个错误的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2021-12-04
    • 2019-08-13
    相关资源
    最近更新 更多