package Magical::Hooker::Decorate;
use strict;
use warnings;
require 5.008001;
use parent qw(DynaLoader);
our $VERSION = '0.03';
$VERSION = eval $VERSION;
sub dl_load_flags { 0x01 }
__PACKAGE__->bootstrap($VERSION);
sub new { bless {}, shift };
__PACKAGE__
__END__
=head1 NAME
Magical::Hooker::Decorate - Decorate an SV using magic hooks
=head1 SYNOPSIS
=head2 From Perl
# this object serves as a namespace, you can only get values that were set
# by it, so you probably want to have a single instance for your module in
# some global variable
my $hooker = Magical::Hooker::Decorate->new;
# associate an SV like this
$hooker->set(\$var, $decoration);
# get the associate value like this:
my $decoration = $hooker->get(\$var);
=head2 From C
magical_hooker_decoration_set(target_sv, decoration_sv, (void *)self);
decoration_sv = magical_hooker_decoration_get(target_sv, (void *)self);
=head1 DESCRIPTION
This module provides a C api and a thin Perl wrapper that lets you associate a
value with any SV, much like L<Hash::Util::FieldHash> does.
The decoration will be reference counted, so C<DESTROY> will be called when
C<target> disappears.
This lets you do things like:
$hooker->set($object, Scope::Guard->new(sub {
warn "object just died";
});
and of course also access the value of the decoration.
The code was used to associate code references created with C<newXS> with their
associated objects in L<Moose>'s experimental XS branch.
=head1 METHODS
=over 4
=item new
Takes no arguments, and returns a handle.
All the association methods use storage that is private to the handle.
=item set $target, $value
Note that C<$target> is dereferenced before casting magic.
=item get $target
Returns the value.
=item clear
Removes the value.
=back
=head1 C API
=over 4
=item MAGIC *magical_hooker_decoration_set (pTHX_ SV *sv, SV *obj, void *ptr)
Creates a new C<MAGIC> entry on C<sv> and stores C<obj> in the C<mg_obj>.
C<mg_ptr> is set to C<ptr>, which allows for namespacing.
In the OO api C<sv> is the dereferenced target, and C<ptr> is the dereferenced C<$self>.
C<ptr> can be C<NULL> but then you're limited to one decoration per SV.
=item SV *magical_hooker_decoration_get (pTHX_ SV *sv, void *ptr)
Get the C<mg_obj>.
=item SV *magical_hooker_decoration_clear (pTHX_ SV *sv, void *ptr)
Removes the C<MAGIC> and returns the C<mg_obj> (after mortalizing it).
=item MAGIC *magical_hooker_decoration_get_mg (pTHX_ SV *sv, void *ptr = NULL)
Get the C<MAGIC> entry in which the decoration is stored.
=back
=head1 THANKS
Shawn M Moore (he knows why)
=head1 VERSION CONTROL
L<http://github.com/nothingmuch/magical-hooker-decorate>
=head1 AUTHOR
Yuval Kogman
=head1 COPYRIGHT & LICENSE
Copyright (c) 2008, 2009 Yuval Kogman. All rights reserved
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
=cut