in reply to Re^7: XS: SvPVLV examples?
in thread XS: SvPVLV examples?

I wonder if each variables with ext magic has its own virtual table pointer.

See SvPVMG & SvPVLV at PerlGuts Illustrated. It's probably somewhat out of date due to the 5.9/5.10 changes, but it is still the clearest guide around.

As I say, for my purposes, the SvPVLV and the associated 'x' type magic would pretty much do everything I want, provided I can adjust the LV_ARGS.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP PCW It is as I've been saying!(Audio until 20090817)

Replies are listed 'Best First'.
Re^9: XS: SvPVLV examples?
by ikegami (Patriarch) on Sep 25, 2009 at 04:03 UTC
    If you're ok with messing with it, here's how:
    use strict; use warnings; use Inline C => <<'__EOI__'; SV* f(SV* sv, I32 pos, I32 len) { SV* targ = newSV_type(SVt_PVLV); sv_magic(targ, NULL, PERL_MAGIC_substr, NULL, 0); LvTYPE(targ) = 'x'; LvTARG(targ) = SvREFCNT_inc_simple(sv); LvTARGOFF(targ) = pos; LvTARGLEN(targ) = len; return targ; } __EOI__ use Devel::Peek qw( Dump ); my $x = "abcde"; $_=uc for f($x,1,3); print("$x\n"); # aBCDe

    If not, just copy the two functions relating to substr in mg.c

      Yep! Bin there, done that. Trouble is, the lvalueness doesn't survive assignment:

      #! perl -slw use strict; use warnings; use Inline C => <<'__EOI__'; SV* f(SV* sv, I32 pos, I32 len) { SV* targ = newSV_type(SVt_PVLV); sv_magic(targ, NULL, PERL_MAGIC_substr, NULL, 0); LvTYPE(targ) = 'x'; LvTARG(targ) = SvREFCNT_inc_simple(sv); LvTARGOFF(targ) = pos; LvTARGLEN(targ) = len; return targ; } __EOI__ use Devel::Peek qw( Dump ); my $x = "abcde"; my $r = f($x,1,3); Dump $r; print $r; __END__ C:\test>ike2-lv.pl SV = PVNV(0x410d558) at 0x97890 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 0 PV = 0x40fa988 "bcd"\0 CUR = 3 LEN = 8 bcd

      The effect I am after is persistant lvalueness as demonstrated here (and back up there somewhere):

      C:\test>perl -MDevel::Peek=Dump -E" $s = 'fred'; $r = \substr $s, 1, 2; $$r = 'oo'; say $s; Dump $_ for $s, $r; $$r = 'eu'; say $s; Dump $_ for $s, $r " food SV = PV(0x16d6f0) at 0x97b60 REFCNT = 3 FLAGS = (POK,pPOK) PV = 0x16b3b8 "food"\0 CUR = 4 LEN = 8 SV = RV(0x97be8) at 0x97bd8 REFCNT = 2 FLAGS = (ROK) RV = 0x97c80 SV = PVLV(0xe2c48) at 0x97c80 REFCNT = 2 FLAGS = (PADMY,GMG,SMG,pPOK) IV = 0 NV = 0 PV = 0x16b478 "oo"\0 CUR = 2 LEN = 8 MAGIC = 0x103708 MG_VIRTUAL = &PL_vtbl_substr MG_TYPE = PERL_MAGIC_substr(x) TYPE = x TARGOFF = 1 TARGLEN = 2 TARG = 0x97b60 SV = PV(0x16d6f0) at 0x97b60 REFCNT = 2 FLAGS = (POK,pPOK) PV = 0x16b3b8 "food"\0 CUR = 4 LEN = 8 feud SV = PV(0x16d6f0) at 0x97b60 REFCNT = 3 FLAGS = (POK,pPOK) PV = 0x16b3b8 "feud"\0 CUR = 4 LEN = 8 SV = RV(0x97be8) at 0x97bd8 REFCNT = 2 FLAGS = (ROK) RV = 0x97c80 SV = PVLV(0xe2c48) at 0x97c80 REFCNT = 2 FLAGS = (PADMY,GMG,SMG,pPOK) IV = 0 NV = 0 PV = 0x16b478 "eu"\0 CUR = 2 LEN = 8 MAGIC = 0x103708 MG_VIRTUAL = &PL_vtbl_substr MG_TYPE = PERL_MAGIC_substr(x) TYPE = x TARGOFF = 1 TARGLEN = 2 TARG = 0x97b60 SV = PV(0x16d6f0) at 0x97b60 REFCNT = 2 FLAGS = (POK,pPOK) PV = 0x16b3b8 "feud"\0 CUR = 4 LEN = 8

      But I'd like to avoid the need for taking a reference and using indirection.

      And to keep this all in one thread: No to "Are you really asking about making an lvalue function?"


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Magic isn't copied on assignment, not even for substr magic.

        You did $r = func for my function, but $r = \func for substr. This difference in the code accounts for the difference in the results.

        If I take your "persistant lvalueness" example and simply change substr to f, I get the same output as before the change.

        Feel free to return a reference to targ instead of targ itself if that's what you want.