возврат списка из Inline: Perl5 дает количество элементов, а не список - PullRequest
11 голосов
/ 02 июля 2019

Некоторый простой код Inline :: Perl5 возвращает список, но кажется, что он возвращает количество элементов, а не фактический список.

Изменение количества участвующих элементов изменяет количество.

use Inline::Perl5;                                             
my $p5 = Inline::Perl5.new;                                    

my $perl5_code = q:to/END/;                                    
   sub p5_data {                                               
      my @monsters = qw( godzilla blob tingler kong dorisday );
      return @monsters;                                        
   }                                                           

   p5_data();                                                  
END                                                            

my @stuff = $p5.run: $perl5_code;                              
say @stuff; # [5]                                              

Я думал, что получу список строк, хранящихся в массиве, но вместо этого он действует так, будто что-то переключает его в скалярный контекст.

Обновление:

Икеами отмечает, что лучше вернуть ссылку на массив:

return \@monsters;

Хотя, тогда вы получите массив в первом элементе @stuff массив, когда вы делаете это:

my @stuff = $p5.run: $perl5_code;                              

Альтернативный подход (из чтения документов Inline :: Perl5) заключается в выполнении $p5.run для определения подпрограммы perl5 и вызова ее из perl6:

my @stuff = $p5.call('p5_data');  

Затем возвращаемый список (return @monsters;) загружается в массив, как я ожидал:

[godzilla blob tingler kong dorisday]

Это недавно установленный Inline :: Perl5 версии 0.40, на «Rakudo Star версии 2019.03.1 построена на MoarVM версии 2019.03, реализующая Perl 6.d ".

Update2: Итак, кажется, что «run» подразумевает скалярный контекст, а «call» является списочным контекстом.

use Inline::Perl5;
my $p5 = Inline::Perl5.new;

my $perl5_defsub = q:to/END/;
   sub whadaya_want {
       wantarray() ? 'LIST' : 'SCALAR';
   }
END

$p5.run: $perl5_defsub;

my $run_context  = $p5.run(  'whadaya_want' );
my $call_context = $p5.call( 'whadaya_want' );  

say "run: ", $run_context;
say "call: ", $call_context;
# run: SCALAR
# call: LIST

Ответы [ 2 ]

6 голосов
/ 03 июля 2019

Ответ Морица объясняет дилемму IP5, но, к сожалению, недооценивает изобретательность Нинера.:)

Основываясь на моем понимании обмена информацией с Niner об этом, текущем IP5 README и обновлениях в ответе Джозефа, IP5 предоставляет четыре варианта.


Вызов P5 sub в списке context:

Inline::Perl5.new.call( 'subname', arg1, arg2 ... )

См. IP5: вызов функции Perl 5 .


Вызовите P5 sub in scalar context:

Inline::Perl5.new.run( 'subname arg1, arg2 ...' )

или

EVAL 'subname arg1, arg2 ...', :lang<Perl5>

См. IP5: запуск произвольного кода Perl 5 .


Вызов метода P5 в списке контекст:

Используйте обычный синтаксис P6:

$p5object.method( arg1, arg2 ... )

для вызова метода method для объекта Perl 5, содержащегося в $p5object, передавая ему arg1 и arg2 в качестве первогодва аргумента.

См. IP5: вызов метода для объекта Perl 5 .


Вызов метода P5 in скалярный контекст:

Используйте обычный синтаксис P6, но также вставьте Scalar в качестве дополнительного первого позиционного аргумента:

$p5object.method( Scalar, arg1, arg2 ... )

для вызова метода method вОбъект Perl 5 содержится в $p5object, передавая ему arg1 и arg2 в качестве первых двух аргументов.

IP5 удаляет Scalar перед вызовом метода Perl 5.

См. IP5: вызов метода в скалярном контексте .


Решение проблем со строками

Imo SO - идеальный способразработать базу знаний об использовании Inlines с P6.Следующее ни в коем случае не предназначено, чтобы препятствовать сообщениям.В самом деле, если вы решите проблему без размещения SO о ней, рассмотрите возможность зайти сюда, чтобы опубликовать вопрос и ответить на пару, документирующую ее.

(культура SO полностью поддерживает такую ​​публикацию вв общем случае, когда один и тот же человек отправляет и вопрос, и ответ и принимает их ответ, но я думаю, что он особенно подходит для тега [perl6] и вдвойне для проблем и решаемых проблем, связанных с Inlines.)

С помощьюОтказавшись от этого, см. также разделы, начинающиеся с Что ожидать при использовании адаптеров для иностранных языков из Мой ответ на Perl6: получение ссылки на массив для модуля Perl5 длямоя попытка найти мини-руководство по решению подобных проблем с P6 Inlines.Это всего лишь первая попытка, и я хотел бы получить обратную связь, особенно о проблемах с ней, поэтому, если вы прочитаете ее, пожалуйста, рассмотрите возможность комментирования там, если какое-либо руководство кажется слишком большим, слишком маленьким или слишком запутанным в каком-либо отношении.ТИА.

6 голосов
/ 02 июля 2019

Perl5::Inline помещает возвращаемые значения в скалярный контекст.

В качестве фона в Perl 5 контекст перетекает внутрь подпрограмм, поэтому подпрограмма всегда знает, в каком контексте она находится.

В Perl6, контекст распространяется наружу, поэтому процедура возвращает объект, который может вести себя по-разному в разных контекстах.

Это несоответствие импеданса между Perl 5 и Perl 6 означает, что Inline::Perl5 должен решить вызывать процедуры Perl 5 в одномконтекст, и это скаляр.

Как указал Икегами, правильное решение состоит в том, чтобы вернуть правильный скаляр, то есть ссылку (в Perl 5 говорят).Ограничения в Inline::Perl5 могут означать, что вам нужно явно разыменовывать на стороне Perl 6.

...