in reply to Marking an array as already seen

John,
I'd like to thank you for asking a good question that has blown my work schedule out of the water and ruined my day ;).

I've wanted the same thing on occasion,(For lazy iterating, etc without tieing blessing, bla,bla) so I did it.
I wrote an XS module using the '~' user defined magic vtable. It respect's other magic and let's specify a name space to avoid collisions. The only problem I have is that I'm trying to set it to use one context sensitive routine for get/set. Once I try and process the argument stack manually it blows up. (Just saying SvOK(target) core dumps.) I'm new to XS and guts so it is probably something stupid I'm doing. The main implementation was quick, but I've been slamming my head off the wall with the optional arugments for like 7 hours. I'll post later today about that problem and then I'll post the module.

When it is it finished it will work like so.
use Magic::Attach; sub bind { my ($ref,$shadow) = @_; attach($ref,$shadow, 'optional namespace'); } # Later sub foo { my $ref = shift; my $shadow = attach($ref); $shadow = attach($ref,{}) unless $shadow; my $count = $shadow->{Someattribute}; }
-Lee

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

Replies are listed 'Best First'.
Re: Re: Marking an array as already seen ('~'magic virtual table)
by John M. Dlugosz (Monsignor) on Jan 18, 2003 at 01:47 UTC
    Interesting. You're saying that in the perl implementation, there is a user-defined "slot" that can hold ... what? A ref to another thing, which you choose to be a hash for your property table, it seems. But you called it a user-defined v-table, like it's a table rather than a single slot. Or maybe that's just the inteded use?

    Care to tell us more about that? Describing it might help gell your knowledge about XS guts.

    —John

      There are different types of magic (this is how tie is implemented amongst other things.), I am using the '~' user extension type. Multiple variables can be attached to a reference as well and as long as they specify a different 'namespace', they won't clobber each other.

      I choose to let my implementation use any ref blessed or not. The table portion refers to additional methods that can be implemented.
      Function pointer Action taken ---------------- ------------ svt_get Do something after the value of the SV is retr +ieved. svt_set Do something after the SV is assigned a value. svt_len Report on the SV's length. svt_clear Clear something the SV represents. svt_free Free any extra storage associated with the SV.
      To get the value bound to the variable, I'm simply returning it's pointer stored in mg_ptr. See the Magic Virtual Tables section in perldoc:perlguts for a better explanation (It's late and I'm bug-eyed tired). I'm only implementing free though it could be extended to open up the other functions. I probably will do that. If I did, let's say you were trying to make a cache of the output of some larger process, you would be able to add a callback to the data structure via set && clear magic that would invalidate that part of the cache when updated and it wouldn't require any direct action by the user.

      The implementation as it stands is exposed through a single routine but this might change as the function attach is almost too DWIM.
      Here's a run down of what it looks like.
      attach ( $somepointer, { seen=>1 }, 'opt_name_to_avoid_collision') or + die "Couldn't attach; # Later on... my $attached = attach($somepointer); $attached->{bar}= uc $attached->{bar};
      Not a compelling example above but I can think of some better ones which I'll post when it's cleaned up. If you think about how matching works and how it tracks where it is in a string, well you can do the same thing with any sub now without trying to compute unique keys from caller() + data and storing it in a hash. Lazily processing lists non-destructively is another good example.

      -Lee

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