Решение - написать $@array
вместо \@array
:
$worksheet.write_row(0,0, $@line)
Остальная часть этого ответа представляет собой краткое руководство по написанию кода с использованием установленных адаптеров иностранного языка и решению любых возникающих проблем. Я предполагаю, что это будет общий ресурс, ответ, который выходит далеко за рамки этого конкретного вопроса.
Он начинается с очевидного вопроса «Почему $@foo
?», Обсуждает, как успешно использовать адаптеры иностранного языка, и заканчивается объяснением, почему предупреждающее сообщение было бесполезным.
Почему $@foo
?
Запись $@foo
для передачи @foo
в качестве ссылки на массив P5 - это простое и естественное использование существующей функции P6.
Тем не менее, пользователям не нужно понимать эту $
особенность P6, и им не нужно знать, как Inline::Perl5
ее использует, чтобы делать то, что они хотят (чтобы написать код P6, который передает ссылку на массив функции из P5 модуль).
Итак, главный ответ на вопрос "почему $@foo
?" в том, что вы так пишете, и это работает. \ o /
Откуда следует знать магические заклинания?
Я получил решение для передачи ссылки на массив из Inline :: Perl5 README:
Ссылки HASH
и ARRAY
создаются автоматически, если объекты Perl 6 помещены в контейнер:
$p5obj.takes-an-array: [<a b c>];
$p5obj.takes-an-array-ref: $[<a b c>];
(Слово «контейнерный» относится к концепции P6, которую lizmat хорошо объясняет тем, кто знает P5 в ее Контейнеры в статье P6. Но контейнеровоз на самом деле технически не имеет отношения к почему $@foo
означает ссылку на массив в P5 при использовании Inline::Perl5
. Да, это работает. Нет, не должно быть таким.)
Почему $@foo
в P6 означает ссылку на массив в P5?
Причина, по которой написание $@foo
является правильным, заключается не в том, что язык P6 или компилятор говорят, что это так.
Это подходящая функция P6, но причина, по которой это правильно, заключается в том, что так говорит niner (автор Inline::Perl5
).
Почему Найнер выбрал $@foo
?
Предположительно потому, что это:
Легко писать для новичков;
Будет иметь смысл для этой цели, когда кто-то узнает P6;
Легко задокументировать;
Легко преобразовать из его значения P6 (Array
в Scalar
) в целевое значение P5 (ссылка на массив P5) эффективным способом.
Чего ожидать при использовании адаптеров для иностранных языков
Inline::Perl5
- один из нескольких языковых адаптеров. Эти адаптеры позволяют коду P6 встраивать код, написанный на этих иностранных языках, и / или использовать модули, написанные на этих иностранных языках.
Когда компилятор Rakudo P6 видит :from<Perl5>
в операторе use
, он неявно вызывает ранее установленный модуль P6 с именем Inline::Perl5
.
Inline::Perl5
устанавливает код маршалинга, который автоматически сопоставляет код P6 с кодом P5 и обратно, так что P6 и P5 могут работать вместе с минимальными усилиями.
В идеале адаптеры просто выполняли бы свою работу, и вам никогда не приходилось бы о них думать. Но:
Хотя очевидной вещью для сопоставления 42
в P6 на всех без исключения иностранных языках является их значение, представляющее целое число 42
, сопоставление не всегда так просто для структур данных более высокого уровня, функций, ссылок и т. Д. Иногда удивительно, что можно написать код P6 (вы можете создать класс P6, который является подклассом класса P5, написав его точно так же, как если бы это был обычный код P6!), но иногда вам нужно следовать правилу (как в этом случае как передать массив P6 в P5 в качестве ссылки на массив). См. Раздел Документация адаптера ниже.
Язык P6 и компилятор не знают, что отображение происходит. Поэтому любые отображаемые ими сообщения об ошибках или предупреждениях могут быть бесполезными и даже вводить в заблуждение. Кроме того, ошибки адаптера отделены от ошибок в P6, в его компиляторах и в используемых модулях на иностранном языке. См. Раздел Предупреждения и ошибки ниже.
Автоматическое сопоставление, выполняемое адаптерами иностранных языков, далеко не автоматическое. Талантливые разработчики должны написать код адаптера, который выполняет всю маршалинг данных, исключений и т. Д.
Учитывая достаточное количество прошедшего времени (лет), адаптер может приблизиться к идеалу, в котором вам никогда не придется думать о существовании адаптера, если вы просто хотите использовать модули или код этого языка в P6. Вы просто используете его, и он всегда работает так же, как и на иностранном языке.
Один из способов быстрее приблизиться к этому идеалу для вас, дорогой читатель, и для всех нас - это использовать сторонние модули через существующие адаптеры и писать SO-вопросы и проблемы с файлами, когда определенные функции кажутся неработающими. Спасибо @con, niner и всем, кто делает это возможным.
Документация по адаптеру
Единственный способ узнать наверняка, какой код P6 вы должны написать, чтобы использовать модуль иностранного языка, который вы использовали через :from<...>
, - это:
Прочтите документацию к модулю иностранного языка, чтобы узнать, чего он ожидает; а потом
Прочтите документацию адаптера, чтобы узнать, как написать соответствующий код P6, который дает иностранному языку и модулю иностранного языка то, что они ожидают.
В этом случае, когда мы говорим об использовании :from<Perl5>
, адаптер - Inline::Perl5
. В настоящее время его документация представляет собой репозиторий проекта github README. Итак, чтобы увидеть, что вы должны написать, чтобы дать P5 и модулю P5 то, что они ожидают, прочтите этот документ.
У каждого адаптера будет своя собственная документация; ссылку можно найти в его списке на modules.perl6.org.
Предупреждения и ошибки
Если что-то пойдет не так при использовании модуля иностранного языка в P6 (что не произойдет при использовании того же кода непосредственно на этом иностранном языке), тогда:
Убедитесь, что вы прочитали соответствующую документацию адаптера;
Если вы получили предупреждение или сообщение об ошибке, обязательно обратитесь к документации адаптера и его очереди проблем, чтобы увидеть, проливает ли он свет на это конкретное сообщение;
Если вы считаете, что есть ошибка в том, как что-то работает (или не работает) в P6 при использовании модуля иностранного языка, который отлично работает при использовании непосредственно на этом иностранном языке, обратитесь к очереди задач адаптера. Например, если вы используете :from<Perl5>
, обратитесь к очереди задач Inline::Perl5
. Если вы решите что-то опубликовать, напишите здесь, если вы не уверены, что это ошибка, или в очередь задач адаптера, если да.
Поскольку язык 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. Он не понимает, что вы пытаетесь настоять на получении ссылки на массив, которую P5 поймет через Inline::Perl5
.
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 работать со ссылкой на массив. Он думает, что вы пытаетесь создать Capture
P6.
Его совет должен интерпретироваться как предлагающий вам написать \(@foo)
вместо \@foo
для создания Capture
, содержащего @foo
.
Он предупредил об использовании \@foo
для обозначения Capture
именно потому, что разработчики P5 могут написать это, думая, что это создаст ссылку на массив.
Таким образом, P6 не знает, что Inline::Perl5
существует, или что он собирается что-то делать с вашим кодом. Вместо этого его совет представляет собой попытку перевести синтаксис и концепции P5, которые, по его мнению, вы используете, в соответствующий синтаксис и концепции P6. Это не попытка посоветовать, как написать код P6, подходящий для отображения на P5 через Inline::Perl5
.
С учетом всего сказанного, я предполагаю, что разработчики адаптеров и разработчики ядра P6 однажды изменят предупреждения и сообщения об ошибках, связанные с P5, в свете проблем с удобством использования, таких как были подняты этим SO.
19.02.2019