解决办法是写$@array而不是\@array:
$worksheet.write_row(0,0, $@line)
本答案的其余部分是关于使用已安装的外语适配器编写代码并处理出现的任何问题的简要指南。我打算把它作为一个通用资源,一个远远超出这个特定问题的答案。
它以明显的问题“为什么$@foo?”开始,讨论如何成功使用外语适配器,最后解释为什么警告消息没有帮助。
为什么是$@foo?
编写$@foo 以将@foo 作为数组引用 传递给P5 是对现有P6 功能的简单而自然的使用。
也就是说,用户不需要了解 P6 的这个 $ 特性,也不需要知道 Inline::Perl5 是如何使用它的,就可以完成他们想做的事情(编写传递数组的 P6 代码引用 P5 模块中的函数)。
所以“为什么是$@foo?”的主要答案是你那样写它并且它有效。 \o/
一个人应该怎么知道魔法咒语?
我得到了从Inline::Perl5's README 传递数组引用的解决方案:
HASH 和 ARRAY 如果 Perl 6 对象被容器化,则会自动进行引用:
$p5obj.takes-an-array: [<a b c>];
$p5obj.takes-an-array-ref: $[<a b c>];
(“集装箱化”这个词指的是一个 P6 概念,lizmat 在她的Containers in P6 文章中为那些了解 P5 的人很好地解释了。但实际上集装箱船在技术上与 为什么 $@foo 的意思并不相关使用 Inline::Perl5 时在 P5 中的数组引用。是的,它有效。不,它不必那样。)
为什么 P6 中的 $@foo 表示 P5 中的数组引用?
之所以写$@foo 是正确,并不是因为 P6 语言或编译器这么说。
它是一个合适的 P6 功能,但它是正确的原因是niner(Inline::Perl5的作者) 这么说。
niner为什么选择$@foo?
大概是因为:
使用外语适配器时会发生什么
Inline::Perl5 是几个foreign language adaptors 之一。这些适配器允许 P6 代码嵌入以这些外语编写的代码和/或使用以这些外语编写的模块。
当 Rakudo P6 编译器在 use 语句中看到 :from<Perl5> 时,它会隐式调用先前安装的名为 Inline::Perl5 的 P6 模块。
Inline::Perl5 安装 marshaling 代码,该代码自动将 P6 代码映射到 P5 代码和从 P5 代码映射,因此 P6 和 P5 可以轻松地协同工作。
理想情况下,适配器只会完成他们的工作,而您永远不必考虑它们。但是:
虽然将 P6 中的 42 映射到任何和所有外语中的显而易见的事情是它们表示整数 42 的值,但对于更高级别的数据结构,映射并不总是那么简单,函数、引用等。有时编写 P6 代码可以完成令人惊奇的事情(您可以创建一个 P6 类,它是 P5 类的子类,就像使用常规 P6 代码一样编写它!)但有时您有遵循规则(如在本例中如何将 P6 数组作为数组引用传递给 P5)。请参阅下面的适配器文档部分。
P6 语言和编译器不知道映射正在进行。因此,它们显示的任何错误或警告消息都可能无济于事,甚至具有误导性。此外,适配器错误与 P6、其编译器和正在使用的外语模块中的错误是分开的。请参阅下面的警告和错误部分。
使外语适配器进行的自动映射远非自动。有才华的开发人员必须编写适配器代码来完成所有数据、异常等的封送处理。
如果经过足够长的时间(年),适配器可能会接近理想状态,如果您只想在 P6 中使用该语言的模块或代码,则无需考虑适配器的存在。您只需使用它,它就始终像在外语中一样工作。
亲爱的读者,对我们所有人来说,一种更快接近理想的方法是通过现有适配器使用外部模块,并在特定功能似乎不起作用时编写 SO 问题和文件问题.感谢@con、niner 以及所有让这一切发生的人。
适配器文档
确定您应该编写什么 P6 代码以使用您通过 :from<...> 使用过的外语模块的唯一方法是:
在本例中,我们正在讨论:from<Perl5> 的使用,适配器为Inline::Perl5。它的文档目前是its github project repo README。因此,要了解您应该写什么来为 P5 和 P5 模块提供他们所期望的内容,请阅读该文档。
每个适配器都有自己的文档;在modules.perl6.org 上查看其列表以获取链接。
警告和错误
如果在 P6 中使用外语模块时出现任何问题(直接在该外语中使用相同的代码时不会出现问题),那么:
确保您已阅读相关适配器的文档;
如果您收到警告或错误消息,请务必参阅适配器的文档及其问题队列,以查看它是否能阐明该特定消息;
如果您认为在使用直接用于该外语时可以正常工作的外语模块时,在 P6 中的工作方式(或不正常)存在错误,请参阅适配器的问题队列。例如,如果您使用的是:from<Perl5>,请参阅Inline::Perl5's issue queue。如果您决定发布某些内容,如果您不确定这是一个错误,请在此处发布,或者如果您是,请在适配器的问题队列中发布。
由于 P6 语言和编译器不知道映射正在进行,警告和错误消息可能会在学习使用涉及以下规则的外语适配器的任何方面的上下文中产生误导,例如 $@foo这个 SO 的规则。
在 P5 问题的情况下,如果 P6 试图帮助 P5 编码人员编写 P6 代码,并且在使用 Inline::Perl5 时尝试适得其反,这可能会加剧这种情况。问题中的例子就是一个很好的例子:
To pass an array, hash or sub to a function in Perl 6, just pass it as is.
P6 认为您可能习惯于使用前缀 \ 编写数组引用。它认为您可能没有意识到您不需要在 P6 中编写斜线。它没有意识到你在坚持通过Inline::Perl5 获取 P5 可以理解的数组引用。
For other uses of Perl 5's ref operator consider binding with ::= instead.
P6 认为你正在尝试做 P5 中通常使用 \ 完成的事情,不是因为你想使用 P5,而是因为你知道 P5,想要在 P6 中完成一些事情而不涉及 P5,并希望完全相同的语法有效。
(顺便说一句,::= 建议肯定帮不上忙——因为::= 还没有实现!)
Parenthesize as (...) if you intended a capture of a single variable.
P6 并不认为您正在尝试使 P5 函数与数组引用一起工作。它认为您正在尝试创建 P6 Capture。
它的建议应该被解释为建议你写\(@foo)而不是\@foo来创建一个包含@foo的Capture。
它已经警告使用 \@foo 来表示 Capture 正是因为 P5 开发人员可能会认为它会创建一个数组引用来编写它。
总之,P6 不知道Inline::Perl5 的存在,也不知道它会对您的代码做任何事情。相反,它的建议是尝试将它认为您正在使用的 P5 语法和概念转换为 P6 中相应的语法和概念。 不是试图建议如何编写适合映射到 P5 的 P6 代码通过Inline::Perl5。
总而言之,我想适配器开发人员和核心 P6 开发人员有可能有一天会根据此 SO 提出的可用性问题修改 P5 相关的警告和错误消息。