从substr返回的LVALUE引用获取索引

时间:2014-02-18 23:05:11

标签: perl

有没有办法从Perl中的LVALUE引用获取索引?

e.g。给出:

$x = "0123456789";
$two = \substr($x, 2, 1);
$four = \substr($x, 4, 1);

$two$four现在引用$x,即

$$two eq '2';
$$four eq '4';

如果您更改其中任何内容,$x的内容将会更改。

我的问题是,是否可以获得引用指向的索引仅给出引用?

e.g。 magic($four) == 4或至少diff_magic($two, $four) == 2

2 个答案:

答案 0 :(得分:2)

ref($ref)给出LVALUE时,$ref是对SvPVLV的引用。

>perl -MDevel::Peek -e"Dump(\substr('abcdefghij', 3, 4))"
SV = IV(0x7eb360) at 0x7eb364
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x7eb284
  SV = PVLV(0x4bf7e4) at 0x7eb284
    REFCNT = 2
    FLAGS = (GMG,SMG)
    IV = 0
    NV = 0
    PV = 0
    MAGIC = 0x49f12c
      MG_VIRTUAL = &PL_vtbl_substr
      MG_TYPE = PERL_MAGIC_substr(x)
    TYPE = x
    TARGOFF = 3
    TARGLEN = 4
    TARG = 0x4a83a4
    FLAGS = 0
    SV = PV(0x7e8b7c) at 0x4a83a4
      REFCNT = 2
      FLAGS = (PADTMP,POK,READONLY,pPOK)
      PV = 0x4ad824 "abcdefghij"\0
      CUR = 10
      LEN = 12

是的,可以使用B

use B qw( svref_2object );

my $ref = \substr('abcdefghij', 3, 4);

my $sv = svref_2object($ref);
die("Not a PVLV\n") if !$sv->isa('B::PVLV');

my $lv_type = $sv->TYPE();
die("Not a substr lvalue\n") if $lv_type ne 'x';

my $targ_ref = $sv->TARG()->object_2svref();
my $ofs      = $sv->TARGOFF();
my $len      = $sv->TARGLEN();

print("substr('$$targ_ref', $ofs, $len)\n");

substr('abcdefghij', 3, 4)

不确定为什么要这样。

答案 1 :(得分:0)

不,这是不可能的。

substr的使用很少见,尤其是作为左值,但它与正则表达式结合使用非常有用。

你所要求的似乎是不必要的。这听起来像一个模块的封装过于聪明。如果你更好地描述你想要做的事情,那么我相信我们可以帮助你。