shotgunefx has asked for the wisdom of the Perl Monks concerning the following question:

I have an xs module that attaches some magic to a variable using Magic Virtual Tables with a type of '~'. Reference Re: Marking an array as already seen ('~'magic virtual table)

How do I preserve other user defined magic?

It says in perlguts,
If sv is not already magical, Perl uses the SvUPGRADE macro to set the SVt_PVMG flag for the sv. Perl then continues by adding it to the beginning of the linked list of magical features. Any prior entry of the same type of magic is deleted. Note that this can be overridden, and multiple instances of the same type of magic can be associated with an SV

My question is, how to override it? I've looked throuh much of the source and googled like hell but cannot find the answer. Any help would be appreciated.

-Lee

"To be civilized is to deny one's nature."

Replies are listed 'Best First'.
Re: XS and preserving magic
by MarkM (Curate) on Jan 17, 2003 at 22:55 UTC

    Disclaimer: I do not think that attaching multiple instances of the same type of magic to an SV is good.

    sv_magicext() does not have as many restrictions as sv_magic() does. (In fact, sv_magic() is implemented in terms of sv_magicext()) You may need to refer to sv.c to determine what arguments sv_magicext() expects for '~' magic.

      Disclaimer: I do not think that attaching multiple instances of the same type of magic to an SV is good.

      May I ask why? Any specific examples? I'm sure there are things I'm missing but, from my perspective, it wasn't worth doing if you couldn't have multiple attachments. Otherwise there is always that long shot of a collision which in my opinion, the vtable would be the last place I ever, ever, ever would look for a problem with a program. (Especially if I was using someone else's module and was not the author)

      The only method it sets is one to decrement the attached reference.

      -Lee

      "To be civilized is to deny one's nature."
Re: XS and preserving magic
by Elian (Parson) on Jan 17, 2003 at 22:52 UTC
    You can always twiddle the list by hand... (While this might, arugably, be considered slightly mad, you're already writing XS--what's one more chunk of sanity? :)
      Thanks Elian, I thought of that but my grasp of internals sucks. I found a module that did 90% of what I wanted (Devel::WeakRef). I stared at it till I could grok it and then modified it. I do think I am starting to get a bit of a handle on things though. :)

      When I didn't see any takers for my question (I'm impatient dammit. Problems like this I have to keep going till I win or I forget where I was), I grepped through the source of 5.8 and 5.6.1 and found the problem. There is no such flag as far as I can tell.

      It'is a bug in perlguts documentation for 5.6.1. Looking at the code for Perl_sv_magic and the same portion in the 5.8 source, the 5.8 source is commented.
      /* sv_magic() refuses to add a magic of the same 'how' as an existing one */ARGG!!!!

      I couldn't find the flag because there was none. In 5.8 you are supposed to use Perl_magicext which is for this purpose. I stole it and some defines and so far works great in 5.6.1. Renamed it to avoid clashes.

      It potentially does have some very interesting applications. I suppose I could add it so the same ref can't be attached twice and it only called as $self->method then you could have some really private objects (If you are into such things.)

      Personally I think it's nice to be able to attach some private info without having to tie or bless something or otherwise muddle up the caller.

      -Lee

      "To be civilized is to deny one's nature."
Re: XS and preserving magic
by pdcawley (Hermit) on Jan 19, 2003 at 17:56 UTC
    You grep the perl source and grab a magic type of your very own that doesn't get stomped on in the unpleasant ways that '~' magic does. But you can't have chr(185) because I'm already using that for Pixie::Info.

    If you want to see how it's done, grab Pixie and take a look at Info.xs

      Thanks for the suggestion. I'll check it out. I ended up using '~' because in 5.8 it doesn't trample it so stole the sv_magicext() function and put it into the xs file and so far seems to work fine with 5.6.1

      -Lee

      "To be civilized is to deny one's nature."
        We tried to use '~' within Pixie, but for a very good reason that I now can't remember, we ended up having to introduce our own magic type.