perl – 内置内联的文档?

前端之家收集整理的这篇文章主要介绍了perl – 内置内联的文档?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我遇到一种情况,我不能以直观的方式禁止警告,因为perl内置了一个内置函数调用.例如
  1. use strict;
  2. use warnings;
  3.  
  4. {
  5. no warnings 'substr'; # no effect
  6. foo(substr('123',4,6)); # out of range but shouldn't emit a warning
  7. }
  8.  
  9. sub foo {
  10. my $s = shift; # warning reported here
  11. # do something
  12. }

运行此代码导致

  1. substr outside of string at c:\temp\foo.pl line 10.

为了禁止警告,我必须在函数内移动no warnings’substr’.

  1. sub foo {
  2. no warnings 'substr'; # works here,but there's no call to substr
  3. my $s = shift; # no warnings here
  4. # do something
  5. }

我可以看到,通过传递代码通过perl -MO = Terse来调用substr是内联的

  1. LISTOP (0x27dcaa8) leave [1]
  2. OP (0x27a402c) enter
  3. COP (0x27dcac8) nextstate
  4. BINOP (0x27dcb00) leaveloop
  5. LOOP (0x27dcb20) enterloop
  6. LISTOP (0x27dcb68) lineseq
  7. COP (0x27dcb88) nextstate
  8. UNOP (0x27dcbc0) entersub [5] # entry point for foo
  9. UNOP (0x27dcbf4) null [148]
  10. OP (0x27dcbdc) pushmark
  11. LISTOP (0x27dcc48) substr [4] # substr gets called here
  12. OP (0x27dcc30) null [3]
  13. SVOP (0x27dcc84) const [6] PV (0x2319944) "123"
  14. SVOP (0x27dcc68) const [7] IV (0x2319904) 4
  15. SVOP (0x27dcc14) const [8] IV (0x231944c) 6
  16. UNOP (0x27dcca0) null [17]
  17. PADOP (0x27dccf4) gv GV (0x2318e5c) *foo

这个优化器行为是否记录在任何地方? perlsub只提到不断的功能内联.鉴于警告正在以错误的方式报告,并且在呼叫的词汇范围内没有警告不起作用,因此我倾向于将其作为错误报告,尽管我不能想到如何合理地固定,同时保持优化.

注意:在Perl 5.16.1中观察到这种情况.

解决方法

正如你从B :: Terse看到的,substr不是内联的.
  1. $perl -MO=Concise,-exec -e'f(substr($_,3,4))'
  2. 1 <0> enter
  3. 2 <;> nextstate(main 1 -e:1) v:{
  4. 3 <0> pushmark s
  5. 4 <#> gvsv[*_] s
  6. 5 <$> const[IV 3] s
  7. 6 <$> const[IV 4] s
  8. 7 <@> substr[t4] sKM/3 <-- The substr operator is evaluated first.
  9. 8 <#> gv[*f] s/EARLYCV
  10. 9 <1> entersub[t5] vKS/TARG <-- The sub call second.
  11. a <@> leave[1 ref] vKP/REFC
  12. -e Syntax OK

当substr被称为左值上下文时,substr返回一个包含传递给substr的操作数的神奇标量.

  1. $perl -MDevel::Peek -e'$_ = "abcdef"; Dump(${\ substr($_,4) })'
  2. SV = PVLV(0x2865d60) at 0x283fbd8
  3. REFCNT = 2
  4. FLAGS = (GMG,SMG) <--- Gets and sets are magical.
  5. IV = 0 GMG: A function that mods the scalar
  6. NV = 0 is called before fetches.
  7. PV = 0 SMG: A function is called after the
  8. MAGIC = 0x2856810 scalar is modified.
  9. MG_VIRTUAL = &PL_vtbl_substr
  10. MG_TYPE = PERL_MAGIC_substr(x)
  11. TYPE = x
  12. TARGOFF = 3 <--- substr's second arg
  13. TARGLEN = 4 <--- substr's third arg
  14. TARG = 0x287bfd0 <--- substr's first arg
  15. FLAGS = 0
  16. SV = PV(0x28407f0) at 0x287bfd0 <--- A dump of substr's first arg
  17. REFCNT = 2
  18. FLAGS = (POK,IsCOW,pPOK)
  19. PV = 0x2865d20 "abcdef"\0
  20. CUR = 6
  21. LEN = 10
  22. COW_REFCNT = 1

子例程参数在lvalue上下文中进行求值,因为Perl [1]中的子程序参数始终通过引用传递.

  1. $perl -E'sub f { $_[0] = "def"; } $x = "abc"; f($x); say $x;'
  2. def

当访问魔法标量时,发生子串操作.

  1. $perl -E'$x = "abc"; $r = \substr($x,1); $x = "def"; say $$r;'
  2. d

这样做可以让substr(…)=“abc”;

>这可能是使用类似于以下的语言记录的:“@_的元素被别名到子例程参数.

猜你在找的Perl相关文章