Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 内置的内联文档?_Perl - Fatal编程技术网

Perl 内置的内联文档?

Perl 内置的内联文档?,perl,Perl,我遇到了一种无法直观地禁止警告的情况,因为perl正在调用内置函数。e、 g use strict; use warnings; { no warnings 'substr'; # no effect foo(substr('123', 4, 6)); # out of range but shouldn't emit a warning } sub foo { my $s = shift; # warning reported here # d

我遇到了一种无法直观地禁止警告的情况,因为perl正在调用内置函数。e、 g

use strict;
use warnings;

{
    no warnings 'substr';      # no effect
    foo(substr('123', 4, 6));  # out of range but shouldn't emit a warning
}

sub foo {
    my $s = shift;  # warning reported here
    # do something
}
运行此代码会导致

substr outside of string at c:\temp\foo.pl line 10.
为了抑制警告,我必须将
no warnings'substr'
移动到函数内部

sub foo {
    no warnings 'substr'; # works here, but there's no call to substr
    my $s = shift;        # no warnings here
    # do something
}
我可以看到对
substr
的调用是通过
perl-MO=Terse

LISTOP (0x27dcaa8) leave [1]
    OP (0x27a402c) enter
    COP (0x27dcac8) nextstate
    BINOP (0x27dcb00) leaveloop
        LOOP (0x27dcb20) enterloop
        LISTOP (0x27dcb68) lineseq
            COP (0x27dcb88) nextstate
            UNOP (0x27dcbc0) entersub [5]          # entry point for foo
                UNOP (0x27dcbf4) null [148]
                    OP (0x27dcbdc) pushmark
                    LISTOP (0x27dcc48) substr [4]  # substr gets called here
                        OP (0x27dcc30) null [3]
                        SVOP (0x27dcc84) const [6] PV (0x2319944) "123"
                        SVOP (0x27dcc68) const [7] IV (0x2319904) 4
                        SVOP (0x27dcc14) const [8] IV (0x231944c) 6
                    UNOP (0x27dcca0) null [17]
                        PADOP (0x27dccf4) gv  GV (0x2318e5c) *foo
是否在任何地方记录了此优化器行为
perlsub
只提到常量函数的内联。考虑到警告被报告在错误的行中,并且
无警告
在调用的词法范围内不起作用,我倾向于将其报告为一个bug,尽管我想不出如何在保持优化的同时合理地修复它


注意:此行为是在Perl 5.16.1中观察到的。

这是一个记录在案的行为(在中):

字符串外部的substr

(W substr),(F)您试图引用指向 在一根绳子的外面。也就是说,偏移量的绝对值为 大于字符串的长度。请参阅perlfunc中的“substr”。 如果substr用于左值上下文(如所示),则此警告是致命的 赋值的左侧,或作为 示例)

我的

将呼叫更改为

foo(my $o = substr('123', 4, 6));
使警告消失

no warnings
移动到sub中不会改变我的行为。你有什么Perl版本?(此处为5.14.4)

我用于测试的代码:

#!/usr/bin/perl
use strict;
use warnings;

$| = 1;

print 1, foo(my $s1 = substr('abc', 4, 6));
print 2, bar(my $s2 = substr('def', 4, 6));

{
    no warnings 'substr';
    print 3, foo(my $s3 = substr('ghi', 4, 6));
    print 4, bar(my $s4 = substr('jkl', 4, 6));
    print 5, bar(substr('mno', 4, 6)); # Stops here, reports line 12.
    print 6, foo(substr('pqr', 4, 6));
}
print "ok\n";

sub foo {
    my $s = shift;
}

sub bar {
    no warnings 'substr';
    my $s = shift;
}
更新:
我在5.10.1中得到了相同的行为,但在5.20.1中,行为与您所描述的一样。

正如您从B::Terse中看到的,
substr
不是内联的

$ perl -MO=Concise,-exec -e'f(substr($_, 3, 4))'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <0> pushmark s
4  <#> gvsv[*_] s
5  <$> const[IV 3] s
6  <$> const[IV 4] s
7  <@> substr[t4] sKM/3        <-- The substr operator is evaluated first.
8  <#> gv[*f] s/EARLYCV
9  <1> entersub[t5] vKS/TARG   <-- The sub call second.
a  <@> leave[1 ref] vKP/REFC
-e syntax OK
子程序参数在左值上下文中求值,因为在Perl[1]中子程序参数总是通过引用传递

子字符串操作在访问神奇标量时发生

$ perl -E'$x = "abc"; $r = \substr($x, 0, 1); $x = "def"; say $$r;'
d
这样做是为了允许
substr(…)=“abc”


  • 这可能是使用与以下类似的语言记录的:“
    @
    的元素被别名化为子例程参数。”

  • 好奇。我正在运行5.16.1;那不是致命的。复制对
    foo
    的调用会导致两个警告。@MichaelCarman:你说得对。在5.20.1中测试,它不会死亡,并在
    foo
    中报告警告。看起来行为在5.16中有所改变。perl5160delta说,如果左值只从读取,而不是写入,那么它现在只是一个警告,就像右值
    substr
    一样。显然,perldiag没有更新以匹配。无论如何,消息的严重性是相切的。主要问题是对
    substr
    的调用首先是内联的。@MichaelCarman:但是,它们似乎是相关的,因为旧版本在正确的行报告了警告。
    “”。substr(…)
    my$temp=substr(…)
    更简单、更容易,因为它没有内联
    substr
    返回一个神奇的值,该值包含作为左值调用时传递给
    substr
    的操作数(例如,作为sub的参数)。子字符串操作在访问神奇值时发生。这样做是为了允许
    substr(…)=“abc”例如
    perl-e'$=“abc”;my$r=\substr($\u0,1)$_=“def”;说$$r;'打印
    d
    @ikegami:我想你找到了真正的答案;请添加您的评论作为一个。我在辩论一个博士补丁<代码>@
    别名导致在左值上下文中解释
    substr
    调用是很微妙的。我针对当前行为提交了。这不是一个bug。//文档已经明确提到了这种情况,所以我不确定您想要什么样的文档更改foreach循环的列表和sub/方法调用的参数都是左值,因为Perl总是通过引用(“别名”)传递。e、 g.
    perl-e'for($x){$\u=“abc”}比如说$x;'
    perl-E'sub{$\u0]=“abc”}->($x);假设$x'
    @ikegami:bug是
    无警告的'substr'
    在触发它的
    substr
    调用出现的词法范围内没有效果。smacks head我不确定为什么我将
    O
    输出解释为执行顺序而不是树。我想我是走错了路,因为“substr out of string”警告被报告发生在
    my$s=shift
    行上,这意味着对
    substr
    的调用被列在那里作为某种模糊的优化,以节省调用开销,我再也找不到回去的路了。叹息
    $ perl -E'sub f { $_[0] = "def"; }  $x = "abc"; f($x); say $x;'
    def
    
    $ perl -E'$x = "abc"; $r = \substr($x, 0, 1); $x = "def"; say $$r;'
    d