Inline:Perl5的列表返回给出项目数,而不是列表

Jos*_*ner 11 perl perl6

一些简单的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]                                              
Run Code Online (Sandbox Code Playgroud)

我以为我会得到存储在数组中的字符串列表,但是相反,它的行为就像是将其切换到标量上下文一样。

更新:

ikeami指出,返回对数组的引用会更好:

return \@monsters;
Run Code Online (Sandbox Code Playgroud)

但是,执行此操作后,您将在@stuff数组的第一个元素中得到一个数组:

my @stuff = $p5.run: $perl5_code;                              
Run Code Online (Sandbox Code Playgroud)

另一种方法(通过阅读Inline :: Perl5文档)是在$p5.run定义a perl5子对象之后,从perl6调用它的:

my @stuff = $p5.call('p5_data');  
Run Code Online (Sandbox Code Playgroud)

然后列表return(return @monsters;)如我所料被加载到数组中:

[godzilla blob tingler kong dorisday]
Run Code Online (Sandbox Code Playgroud)

这是最近安装的Inline :: Perl5版本0.40,位于“基于实现Perl 6.d的MoarVM版本2019.03构建的Rakudo Star版本2019.03.1”上。

Update2:因此,似乎“运行”表示标量上下文,而“调用”表示列表上下文。

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
Run Code Online (Sandbox Code Playgroud)

rai*_*iph 8

莫里茨(Moritz)的回答解释了IP5的困境,但是,艾伊(Alui)低估了niner的独创性。:)

根据我对前不久与niner进行的交流,当前的IP5自述文件以及约瑟夫的回答中的更新的理解,IP5提供了四个选项。


列表上下文中调用P5

Inline::Perl5.new.call( 'subname', arg1, arg2 ... )
Run Code Online (Sandbox Code Playgroud)

请参阅IP5:调用Perl 5函数


标量上下文中调用P5

Inline::Perl5.new.run( 'subname arg1, arg2 ...' )
Run Code Online (Sandbox Code Playgroud)

要么

EVAL 'subname arg1, arg2 ...', :lang<Perl5>
Run Code Online (Sandbox Code Playgroud)

请参阅IP5:运行任意Perl 5代码


列表上下文中调用P5 方法

使用常规的P6语法:

$p5object.method( arg1, arg2 ... )
Run Code Online (Sandbox Code Playgroud)

调用method在保持一个Perl 5对象的方法$p5object传递给它arg1arg2作为其第一个两个参数。

请参见IP5:在Perl 5对象上调用方法


标量上下文中调用P5 方法

使用常规的P6语法,但也可以Scalar作为额外的第一个位置参数插入:

$p5object.method( Scalar, arg1, arg2 ... )
Run Code Online (Sandbox Code Playgroud)

调用method在保持一个Perl 5对象的方法$p5object传递给它arg1arg2作为其第一个两个参数。

IP5会Scalar在调用Perl 5方法之前删除。

请参阅IP5:在标量上下文中调用方法


处理内联的问题

Imo SO帖子是围绕Inline与P6一起使用开发知识库的理想方法。以下内容绝不阻止发布问题。

(实际上,这绝不是阻止发布问题和回答您自己的问题的方式 - “提出并回答您自己的问题不仅可以,而且受到明确鼓励”“为此内置的功能”到“回答自己的问题-分享您的知识,Q&A式”1。我觉得这个方法尤其适用于在[perl6]标签和双所以对问题和相关的内联解决的问题)

与前述的出路,也看到了部分开始什么用外语适配器时期望我的回答对Perl6:让数组引用了Perl5的模块对我在上处理与P6内联类似的问题一个小型通用指南尝试。这只是第一次尝试,我很想获得反馈,尤其是有关它的问题,因此,如果您阅读了它,请考虑在指南中有任何内容似乎太多,太多或太混乱时在此进行评论。TIA。

脚注

1 @BradGilbert在下面的评论中建议在发布问题和回答问题之间延迟。我可以看到的优点是,让人们有时间就问题的措辞给出反馈,也许还可以看看是否有人选择写出比您所想的更好的答案。但是,如果您确实打算延迟回答,请在问题的顶部说您打算回答。


mor*_*itz 6

Perl5::Inline 将返回值放入标量上下文。

作为背景,在Perl 5中,上下文向内流入例程,因此例程始终知道它在哪个上下文中。

In Perl 6, context flows outwards, so a routine returns an object that can behave differently in different context.

This impedance mismatch between Perl 5 and Perl 6 means that Inline::Perl5 has to decide to call Perl 5 routines in one context, and that's scalar.

As ikegami pointed out, the proper solution is to return a proper scalar, aka reference (in Perl 5 speak). Limitations in Inline::Perl5 might mean you need to explicitly dereference on the Perl 6 side.

  • 你知道,我觉得很奇怪的是,有些人不明白为什么不是每个人都喜欢 stackoverflow。我将对我的问题进行另一次更新,以便以可读的方式进入我的代码。 (2认同)