]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - lib/Variable/Magic.pm
Remove one extra mention to MGf_COPY
[perl/modules/Variable-Magic.git] / lib / Variable / Magic.pm
index eca6f03446ca6599c4e1291d9e4a30e023ffca19..29b8fa118cdf054eca0bfd12a37f83747970568b 100644 (file)
@@ -5,59 +5,97 @@ use 5.008;
 use strict;
 use warnings;
 
-use Carp qw/croak/;
-
 =head1 NAME
 
 Variable::Magic - Associate user-defined magic to variables from Perl.
 
 =head1 VERSION
 
-Version 0.30
+Version 0.49
 
 =cut
 
 our $VERSION;
 BEGIN {
- $VERSION = '0.30';
+ $VERSION = '0.49';
 }
 
 =head1 SYNOPSIS
 
-    use Variable::Magic qw/wizard cast dispell/;
-
-    my $wiz = wizard set => sub { print STDERR "now set to ${$_[0]}!\n" };
-    my $a = 1;
-    cast $a, $wiz;
-    $a = 2;          # "now set to 2!"
-    dispell $a, $wiz;
-    $a = 3           # (nothing)
+    use Variable::Magic qw<wizard cast VMG_OP_INFO_NAME>;
+
+    { # A variable tracer
+     my $wiz = wizard(
+      set  => sub { print "now set to ${$_[0]}!\n" },
+      free => sub { print "destroyed!\n" },
+     );
+
+     my $a = 1;
+     cast $a, $wiz;
+     $a = 2;        # "now set to 2!"
+    }               # "destroyed!"
+
+    { # A hash with a default value
+     my $wiz = wizard(
+      data     => sub { $_[1] },
+      fetch    => sub { $_[2] = $_[1] unless exists $_[0]->{$_[2]}; () },
+      store    => sub { print "key $_[2] stored in $_[-1]\n" },
+      copy_key => 1,
+      op_info  => VMG_OP_INFO_NAME,
+     );
+
+     my %h = (_default => 0, apple => 2);
+     cast %h, $wiz, '_default';
+     print $h{banana}, "\n"; # "0" (there is no 'banana' key in %h)
+     $h{pear} = 1;           # "key pear stored in helem"
+    }
 
 =head1 DESCRIPTION
 
-Magic is Perl way of enhancing objects.
-This mechanism let the user add extra data to any variable and hook syntaxical operations (such as access, assignation or destruction) that can be applied to it.
-With this module, you can add your own magic to any variable without the pain of the C API.
+Magic is Perl's way of enhancing variables.
+This mechanism lets the user add extra data to any variable and hook syntactical operations (such as access, assignment or destruction) that can be applied to it.
+With this module, you can add your own magic to any variable without having to write a single line of XS.
 
-Magic differs from tieing and overloading in several ways :
+You'll realize that these magic variables look a lot like tied variables.
+It is not surprising, as tied variables are implemented as a special kind of magic, just like any 'irregular' Perl variable : scalars like C<$!>, C<$(> or C<$^W>, the C<%ENV> and C<%SIG> hashes, the C<@ISA> array,  C<vec()> and C<substr()> lvalues, L<threads::shared> variables...
+They all share the same underlying C API, and this module gives you direct access to it.
+
+Still, the magic made available by this module differs from tieing and overloading in several ways :
 
 =over 4
 
 =item *
 
-Magic isn't copied on assignation (as for blessed references) : you attach it to variables, not values.
+Magic is not copied on assignment.
+
+You attach it to variables, not values (as for blessed references).
 
 =item *
 
-It doesn't replace the original semantics : magic callbacks trigger before the original action take place, and can't prevent it to happen.
+Magic does not replace the original semantics.
+
+Magic callbacks usually get triggered before the original action takes place, and cannot prevent it from happening.
+This also makes catching individual events easier than with C<tie>, where you have to provide fallbacks methods for all actions by usually inheriting from the correct C<Tie::Std*> class and overriding individual methods in your own class.
 
 =item *
 
-It's mostly invisible at the Perl level : magical and non-magical variables cannot be distinguished with C<ref>, C<reftype> or another trick.
+Magic is type-agnostic.
+
+The same magic can be applied on scalars, arrays, hashes, subs or globs.
+But the same hook (see below for a list) may trigger differently depending on the the type of the variable.
 
 =item *
 
-It's notably faster, since perl's way of handling magic is lighter by nature, and there's no need for any method resolution.
+Magic is invisible at the Perl level.
+
+Magical and non-magical variables cannot be distinguished with C<ref>, C<tied> or another trick.
+
+=item *
+
+Magic is notably faster.
+
+Mainly because perl's way of handling magic is lighter by nature, and because there is no need for any method resolution.
+Also, since you don't have to reimplement all the variable semantics, you only pay for what you actually use.
 
 =back
 
@@ -69,21 +107,23 @@ The operations that can be overloaded are :
 
 C<get>
 
-This magic is invoked when the variable is evaluated (does not include array/hash subscripts and slices).
+This magic is invoked when the variable is evaluated.
+It is never called for arrays and hashes.
 
 =item *
 
 C<set>
 
-This one is triggered each time the value of the variable changes (includes array/hash subscripts and slices).
+This magic is called each time the value of the variable changes.
+It is called for array subscripts and slices, but never for hashes.
 
 =item *
 
 C<len>
 
-This magic is a little special : it is called when the 'size' or the 'length' of the variable has to be known by Perl.
-Typically, it's the magic involved when an array is evaluated in scalar context, but also on array assignation and loops (C<for>, C<map> or C<grep>).
-The callback has then to return the length as an integer.
+This magic only applies to scalars and arrays, and is triggered when the 'size' or the 'length' of the variable has to be known by Perl.
+This is typically the magic involved when an array is evaluated in scalar context, but also on array assignment and loops (C<for>, C<map> or C<grep>).
+The length is returned from the callback as an integer.
 
 =item *
 
@@ -96,34 +136,31 @@ Please note that this is different from undefining the variable, even though the
 
 C<free>
 
-This one can be considered as an object destructor.
-It happens when the variable goes out of scope (with the exception of global scope), but not when it is undefined.
+This magic is called when an object is destroyed as the result of the variable going out of scope (but not when the variable is undefined).
 
 =item *
 
 C<copy>
 
-This magic only applies to tied arrays and hashes.
-It fires when you try to access or change their elements.
-It is available on your perl iff C<MGf_COPY> is true.
+This magic only applies to tied arrays and hashes, and fires when you try to access or change their elements.
 
 =item *
 
 C<dup>
 
-Invoked when the variable is cloned across threads.
-Currently not available.
+This magic is invoked when the variable is cloned across threads.
+It is currently not available.
 
 =item *
 
 C<local>
 
 When this magic is set on a variable, all subsequent localizations of the variable will trigger the callback.
-It is available on your perl iff C<MGf_LOCAL> is true.
+It is available on your perl if and only if C<MGf_LOCAL> is true.
 
 =back
 
-The following actions only apply to hashes and are available iff C<VMG_UVAR> is true.
+The following actions only apply to hashes and are available if and only if L</VMG_UVAR> is true.
 They are referred to as C<uvar> magics.
 
 =over 4
@@ -132,7 +169,7 @@ They are referred to as C<uvar> magics.
 
 C<fetch>
 
-This magic happens each time an element is fetched from the hash.
+This magic is invoked each time an element is fetched from the hash.
 
 =item *
 
@@ -150,357 +187,480 @@ This magic fires when a key is tested for existence in the hash.
 
 C<delete>
 
-This last one triggers when a key is deleted in the hash, regardless of whether the key actually exists in it.
+This magic is triggered when a key is deleted in the hash, regardless of whether the key actually exists in it.
 
 =back
 
 You can refer to the tests to have more insight of where the different magics are invoked.
 
-To prevent any clash between different magics defined with this module, an unique numerical signature is attached to each kind of magic (i.e. each set of callbacks for magic operations).
+=head1 FUNCTIONS
 
-=head1 PERL MAGIC HISTORY
+=cut
 
-The places where magic is invoked have changed a bit through perl history.
-Here's a little list of the most recent ones.
+BEGIN {
+ require XSLoader;
+ XSLoader::load(__PACKAGE__, $VERSION);
+}
+
+=head2 C<wizard>
+
+    wizard(
+     data     => sub { ... },
+     get      => sub { my ($ref, $data [, $op]) = @_; ... },
+     set      => sub { my ($ref, $data [, $op]) = @_; ... },
+     len      => sub {
+      my ($ref, $data, $len [, $op]) = @_; ... ; return $newlen
+     },
+     clear    => sub { my ($ref, $data [, $op]) = @_; ... },
+     free     => sub { my ($ref, $data [, $op]) = @_, ... },
+     copy     => sub { my ($ref, $data, $key, $elt [, $op]) = @_; ... },
+     local    => sub { my ($ref, $data [, $op]) = @_; ... },
+     fetch    => sub { my ($ref, $data, $key [, $op]) = @_; ... },
+     store    => sub { my ($ref, $data, $key [, $op]) = @_; ... },
+     exists   => sub { my ($ref, $data, $key [, $op]) = @_; ... },
+     delete   => sub { my ($ref, $data, $key [, $op]) = @_; ... },
+     copy_key => $bool,
+     op_info  => [ 0 | VMG_OP_INFO_NAME | VMG_OP_INFO_OBJECT ],
+    )
+
+This function creates a 'wizard', an opaque object that holds the magic information.
+It takes a list of keys / values as argument, whose keys can be :
 
 =over 4
 
 =item *
 
-B<5.6.x>
+C<data>
 
-I<p14416> : 'copy' and 'dup' magic.
+A code (or string) reference to a private data constructor.
+It is called in scalar context each time the magic is cast onto a variable, with C<$_[0]> being a reference to this variable and C<@_[1 .. @_-1]> being all extra arguments that were passed to L</cast>.
+The scalar returned from this call is then attached to the variable and can be retrieved later with L</getdata>.
 
 =item *
 
-B<5.8.9>
+C<get>, C<set>, C<len>, C<clear>, C<free>, C<copy>, C<local>, C<fetch>, C<store>, C<exists> and C<delete>
 
-I<p28160> : Integration of I<p25854> (see below).
+Code (or string) references to the respective magic callbacks.
+You don't have to specify all of them : the magic corresponding to undefined entries will simply not be hooked.
 
-I<p32542> : Integration of I<p31473> (see below).
+When those callbacks are executed, C<$_[0]> is a reference to the magic variable and C<$_[1]> is the associated private data (or C<undef> when no private data constructor is supplied with the wizard).
+Other arguments depend on which kind of magic is involved :
+
+=over 8
 
 =item *
 
-B<5.9.3>
+C<len>
 
-I<p25854> : 'len' magic is no longer called when pushing an element into a magic array.
+C<$_[2]> contains the natural, non-magical length of the variable (which can only be a scalar or an array as len magic is only relevant for these types).
+The callback is expected to return the new scalar or array length to use, or C<undef> to default to the normal length.
 
-I<p26569> : 'local' magic.
+=item *
+
+C<copy>
+
+C<$_[2]> is a either an alias or a copy of the current key, and C<$_[3]> is an alias to the current element (i.e. the value).
+Because C<$_[2]> might be a copy, it is useless to try to change it or cast magic on it.
 
 =item *
 
-B<5.9.5>
+C<fetch>, C<store>, C<exists> and C<delete>
 
-I<p31064> : Meaningful 'uvar' magic.
+C<$_[2]> is an alias to the current key.
+Note that C<$_[2]> may rightfully be readonly if the key comes from a bareword, and as such it is unsafe to assign to it.
+You can ask for a copy instead by passing C<< copy_key => 1 >> to L</wizard> which, at the price of a small performance hit, allows you to safely assign to C<$_[2]> in order to e.g. redirect the action to another key.
 
-I<p31473> : 'clear' magic wasn't invoked when undefining an array.
-The bug is fixed as of this version.
+=back
+
+Finally, if C<< op_info => $num >> is also passed to C<wizard>, then one extra element is appended to C<@_>.
+Its nature depends on the value of C<$num> :
+
+=over 8
 
 =item *
 
-B<5.10.0>
+C<VMG_OP_INFO_NAME>
 
-Since C<PERL_MAGIC_uvar> is uppercased, C<hv_magic_check()> triggers 'copy' magic on hash stores for (non-tied) hashes that also have 'uvar' magic.
+C<$_[-1]> is the current op name.
 
 =item *
 
-B<5.11.x>
+C<VMG_OP_INFO_OBJECT>
 
-I<p32969> : 'len' magic is no longer invoked when calling C<length> with a magical scalar.
+C<$_[-1]> is the C<B::OP> object for the current op.
 
-I<p34908> : 'len' magic is no longer called when pushing / unshifting an element into a magical array in void context.
-The C<push> part was already covered by I<p25854>.
+=back
+
+Both result in a small performance hit, but just getting the name is lighter than getting the op object.
+
+These callbacks are executed in scalar context and are expected to return an integer, which is then passed straight to the perl magic API.
+However, only the return value of the C<len> callback currently holds a meaning.
 
 =back
 
-=head1 CONSTANTS
+Each callback can be specified as :
 
-=head2 C<SIG_MIN>
+=over 4
 
-The minimum integer used as a signature for user-defined magic.
+=item *
 
-=head2 C<SIG_MAX>
+a code reference, which will be called as a subroutine.
 
-The maximum integer used as a signature for user-defined magic.
+=item *
 
-=head2 C<SIG_NBR>
+a string reference, where the string denotes which subroutine is to be called when magic is triggered.
+If the subroutine name is not fully qualified, then the current package at the time the magic is invoked will be used instead.
 
-    SIG_NBR = SIG_MAX - SIG_MIN + 1
+=item *
 
-=head2 C<MGf_COPY>
+a reference to C<undef>, in which case a no-op magic callback is installed instead of the default one.
+This may especially be helpful for 'local' magic, where an empty callback prevents magic from being copied during localization.
 
-Evaluates to true iff the 'copy' magic is available.
+=back
 
-=head2 C<MGf_DUP>
+Note that C<free> callbacks are I<never> called during global destruction, as there is no way to ensure that the wizard object and the C<free> callback were not destroyed before the variable.
 
-Evaluates to true iff the 'dup' magic is available.
+Here is a simple usage example :
 
-=head2 C<MGf_LOCAL>
+    # A simple scalar tracer
+    my $wiz = wizard(
+     get  => sub { print STDERR "got ${$_[0]}\n" },
+     set  => sub { print STDERR "set to ${$_[0]}\n" },
+     free => sub { print STDERR "${$_[0]} was deleted\n" },
+    );
 
-Evaluates to true iff the 'local' magic is available.
+=cut
 
-=head2 C<VMG_UVAR>
+sub wizard {
+ if (@_ % 2) {
+  require Carp;
+  Carp::croak('Wrong number of arguments for wizard()');
+ }
 
-When this constant is true, you can use the C<fetch,store,exists,delete> callbacks on hashes.
+ my %opts = @_;
 
-=head2 C<VMG_COMPAT_ARRAY_PUSH_NOLEN>
+ my @keys = qw<op_info data get set len clear free copy dup>;
+ push @keys, 'local' if MGf_LOCAL;
+ push @keys, qw<fetch store exists delete copy_key> if VMG_UVAR;
 
-True for perls that don't call 'len' magic when you push an element in a magical array.
+ my ($wiz, $err);
+ {
+  local $@;
+  $wiz = eval { _wizard(map $opts{$_}, @keys) };
+  $err = $@;
+ }
+ if ($err) {
+  $err =~ s/\sat\s+.*?\n//;
+  require Carp;
+  Carp::croak($err);
+ }
 
-=head2 C<VMG_COMPAT_ARRAY_UNSHIFT_NOLEN_VOID>
+ return $wiz;
+}
 
-True for perls that don't call 'len' magic when you unshift in void context an element in a magical array.
+=head2 C<cast>
 
-=head2 C<VMG_COMPAT_ARRAY_UNDEF_CLEAR>
+    cast [$@%&*]var, $wiz, @args
 
-True for perls that call 'clear' magic when undefining magical arrays.
+This function associates C<$wiz> magic to the supplied variable, without overwriting any other kind of magic.
+It returns true on success or when C<$wiz> magic is already attached, and croaks on error.
+When C<$wiz> provides a data constructor, it is called just before magic is cast onto the variable, and it receives a reference to the target variable in C<$_[0]> and the content of C<@args> in C<@_[1 .. @args]>.
+Otherwise, C<@args> is ignored.
 
-=head2 C<VMG_COMPAT_SCALAR_LENGTH_NOLEN>
+    # Casts $wiz onto $x, passing (\$x, '1') to the data constructor.
+    my $x;
+    cast $x, $wiz, 1;
 
-True for perls that don't call 'len' magic when taking the C<length> of a magical scalar.
+The C<var> argument can be an array or hash value.
+Magic for these scalars behaves like for any other, except that it is dispelled when the entry is deleted from the container.
+For example, if you want to call C<POSIX::tzset> each time the C<'TZ'> environment variable is changed in C<%ENV>, you can use :
 
-=head2 C<VMG_PERL_PATCHLEVEL>
+    use POSIX;
+    cast $ENV{TZ}, wizard set => sub { POSIX::tzset(); () };
 
-The perl patchlevel this module was built with, or C<0> for non-debugging perls.
+If you want to handle the possible deletion of the C<'TZ'> entry, you must also specify C<store> uvar magic.
 
-=head2 C<VMG_THREADSAFE>
+=head2 C<getdata>
 
-True iff this module could have been built with thread-safety features enabled.
+    getdata [$@%&*]var, $wiz
 
-=head2 C<VMG_OP_INFO_NAME>
+This accessor fetches the private data associated with the magic C<$wiz> in the variable.
+It croaks when C<$wiz> does not represent a valid magic object, and returns an empty list if no such magic is attached to the variable or when the wizard has no data constructor.
 
-Value to pass with C<op_info> to get the current op name in the magic callbacks.
+    # Get the data attached to $wiz in $x, or undef if $wiz
+    # did not attach any.
+    my $data = getdata $x, $wiz;
 
-=head2 C<VMG_OP_INFO_OBJECT>
+=head2 C<dispell>
 
-Value to pass with C<op_info> to get a C<B::OP> object representing the current op in the magic callbacks.
+    dispell [$@%&*]variable, $wiz
 
-=head1 FUNCTIONS
+The exact opposite of L</cast> : it dissociates C<$wiz> magic from the variable.
+This function returns true on success, C<0> when no magic represented by C<$wiz> could be found in the variable, and croaks if the supplied wizard is invalid.
 
-=cut
+    # Dispell now.
+    die 'no such magic in $x' unless dispell $x, $wiz;
 
-BEGIN {
- require XSLoader;
- XSLoader::load(__PACKAGE__, $VERSION);
-}
+=head1 CONSTANTS
 
-=head2 C<wizard>
+=head2 C<MGf_COPY>
 
-    wizard sig      => ...,
-           data     => sub { ... },
-           get      => sub { my ($ref, $data [, $op]) = @_; ... },
-           set      => sub { my ($ref, $data [, $op]) = @_; ... },
-           len      => sub { my ($ref, $data, $len [, $op]) = @_; ... ; return $newlen; },
-           clear    => sub { my ($ref, $data [, $op]) = @_; ... },
-           free     => sub { my ($ref, $data [, $op]) = @_, ... },
-           copy     => sub { my ($ref, $data, $key, $elt [, $op]) = @_; ... },
-           local    => sub { my ($ref, $data [, $op]) = @_; ... },
-           fetch    => sub { my ($ref, $data, $key [, $op]) = @_; ... },
-           store    => sub { my ($ref, $data, $key [, $op]) = @_; ... },
-           exists   => sub { my ($ref, $data, $key [, $op]) = @_; ... },
-           delete   => sub { my ($ref, $data, $key [, $op]) = @_; ... },
-           copy_key => $bool,
-           op_info  => [ 0 | VMG_OP_INFO_NAME | VMG_OP_INFO_OBJECT ]
-
-This function creates a 'wizard', an opaque type that holds the magic information.
-It takes a list of keys / values as argument, whose keys can be :
+Evaluates to true if and only if the 'copy' magic is available.
+This is the case for perl 5.7.3 and greater, which is ensured by the requirements of this module.
 
-=over 4
+=head2 C<MGf_DUP>
 
-=item *
+Evaluates to true if and only if the 'dup' magic is available.
+This is the case for perl 5.7.3 and greater, which is ensured by the requirements of this module.
 
-C<sig>
+=head2 C<MGf_LOCAL>
 
-The numerical signature.
-If not specified or undefined, a random signature is generated.
-If the signature matches an already defined magic, then the existant magic object is returned.
+Evaluates to true if and only if the 'local' magic is available.
+This is the case for perl 5.9.3 and greater.
 
-=item *
+=head2 C<VMG_UVAR>
 
-C<data>
+When this constant is true, you can use the C<fetch,store,exists,delete> callbacks on hashes.
+Initial L</VMG_UVAR> capability was introduced in perl 5.9.5, with a fully functional implementation shipped with perl 5.10.0.
 
-A code reference to a private data constructor.
-It is called each time this magic is cast on a variable, and the scalar returned is used as private data storage for it.
-C<$_[0]> is a reference to the magic object and C<@_[1 .. @_-1]> are all extra arguments that were passed to L</cast>.
+=head2 C<VMG_COMPAT_SCALAR_LENGTH_NOLEN>
 
-=item *
+True for perls that don't call 'len' magic when taking the C<length> of a magical scalar.
 
-C<get>, C<set>, C<len>, C<clear>, C<free>, C<copy>, C<local>, C<fetch>, C<store>, C<exists> and C<delete>
+=head2 C<VMG_COMPAT_ARRAY_PUSH_NOLEN>
 
-Code references to the corresponding magic callbacks.
-You don't have to specify all of them : the magic associated with undefined entries simply won't be hooked.
-In those callbacks, C<$_[0]> is always a reference to the magic object and C<$_[1]> is always the private data (or C<undef> when no private data constructor was supplied).
+True for perls that don't call 'len' magic when you push an element in a magical array.
+Starting from perl 5.11.0, this only refers to pushes in non-void context and hence is false.
 
-Moreover, when you pass C<< op_info => $num >> to C<wizard>, the last element of C<@_> will be the current op name if C<$num == VMG_OP_INFO_NAME> and a C<B::OP> object representing the current op if C<$num == VMG_OP_INFO_OBJECT>.
-Both have a performance hit, but just getting the name is lighter than getting the op object.
+=head2 C<VMG_COMPAT_ARRAY_PUSH_NOLEN_VOID>
 
-Other arguments are specific to the magic hooked :
+True for perls that don't call 'len' magic when you push in void context an element in a magical array.
 
-=over 8
+=head2 C<VMG_COMPAT_ARRAY_UNSHIFT_NOLEN_VOID>
 
-=item *
+True for perls that don't call 'len' magic when you unshift in void context an element in a magical array.
 
-C<len>
+=head2 C<VMG_COMPAT_ARRAY_UNDEF_CLEAR>
 
-When the variable is an array or a scalar, C<$_[2]> contains the non-magical length.
-The callback can return the new scalar or array length to use, or C<undef> to default to the normal length.
+True for perls that call 'clear' magic when undefining magical arrays.
 
-=item *
+=head2 C<VMG_COMPAT_HASH_DELETE_NOUVAR_VOID>
 
-C<copy>
+True for perls that don't call 'delete' uvar magic when you delete an element from a hash in void context.
 
-C<$_[2]> is a either a copy or an alias of the current key, which means that it is useless to try to change or cast magic on it.
-C<$_[3]> is an alias to the current element (i.e. the value).
+=head2 C<VMG_COMPAT_GLOB_GET>
 
-=item *
+True for perls that call 'get' magic for operations on globs.
 
-C<fetch>, C<store>, C<exists> and C<delete>
+=head2 C<VMG_PERL_PATCHLEVEL>
 
-C<$_[2]> is an alias to the current key.
-Nothing prevents you from changing it, but be aware that there lurk dangerous side effects.
-For example, it may righteously be readonly if the key was a bareword.
-You can get a copy instead by passing C<< copy_key => 1 >> to L</wizard>, which allows you to safely assign to C<$_[2]> in order to e.g. redirect the action to another key.
-This however has a little performance drawback because of the copy.
+The perl patchlevel this module was built with, or C<0> for non-debugging perls.
 
-=back
+=head2 C<VMG_THREADSAFE>
 
-All the callbacks are expected to return an integer, which is passed straight to the perl magic API.
-However, only the return value of the C<len> callback currently holds a meaning.
+True if and only if this module could have been built with thread-safety features enabled.
 
-=back
+=head2 C<VMG_FORKSAFE>
 
-    # A simple scalar tracer
-    my $wiz = wizard get  => sub { print STDERR "got ${$_[0]}\n" },
-                     set  => sub { print STDERR "set to ${$_[0]}\n" },
-                     free => sub { print STDERR "${$_[0]} was deleted\n" }
+True if and only if this module could have been built with fork-safety features enabled.
+This is always true except on Windows where it is false for perl 5.10.0 and below.
 
-=cut
+=head2 C<VMG_OP_INFO_NAME>
 
-sub wizard {
- croak 'Wrong number of arguments for wizard()' if @_ % 2;
- my %opts = @_;
- my @keys = qw/sig data op_info get set len clear free/;
- push @keys, 'copy'  if MGf_COPY;
- push @keys, 'dup'   if MGf_DUP;
- push @keys, 'local' if MGf_LOCAL;
- push @keys, qw/fetch store exists delete copy_key/ if VMG_UVAR;
- my $ret = eval { _wizard(map $opts{$_}, @keys) };
- if (my $err = $@) {
-  $err =~ s/\sat\s+.*?\n//;
-  croak $err;
- }
- return $ret;
-}
+Value to pass with C<op_info> to get the current op name in the magic callbacks.
 
-=head2 C<gensig>
+=head2 C<VMG_OP_INFO_OBJECT>
 
-With this tool, you can manually generate random magic signature between SIG_MIN and SIG_MAX inclusive.
-That's the way L</wizard> creates them when no signature is supplied.
+Value to pass with C<op_info> to get a C<B::OP> object representing the current op in the magic callbacks.
 
-    # Generate a signature
-    my $sig = gensig;
+=head1 COOKBOOK
+
+=head2 Associate an object to any perl variable
+
+This technique can be useful for passing user data through limited APIs.
+It is similar to using inside-out objects, but without the drawback of having to implement a complex destructor.
+
+    {
+     package Magical::UserData;
+
+     use Variable::Magic qw<wizard cast getdata>;
+
+     my $wiz = wizard data => sub { \$_[1] };
+
+     sub ud (\[$@%*&]) : lvalue {
+      my ($var) = @_;
+      my $data = &getdata($var, $wiz);
+      unless (defined $data) {
+       $data = \(my $slot);
+       &cast($var, $wiz, $slot)
+                 or die "Couldn't cast UserData magic onto the variable";
+      }
+      $$data;
+     }
+    }
+
+    {
+     BEGIN { *ud = \&Magical::UserData::ud }
+
+     my $cb;
+     $cb = sub { print 'Hello, ', ud(&$cb), "!\n" };
+
+     ud(&$cb) = 'world';
+     $cb->(); # Hello, world!
+    }
+
+=head2 Recursively cast magic on datastructures
+
+C<cast> can be called from any magical callback, and in particular from C<data>.
+This allows you to recursively cast magic on datastructures :
+
+    my $wiz;
+    $wiz = wizard data => sub {
+     my ($var, $depth) = @_;
+     $depth ||= 0;
+     my $r = ref $var;
+     if ($r eq 'ARRAY') {
+      &cast((ref() ? $_ : \$_), $wiz, $depth + 1) for @$var;
+     } elsif ($r eq 'HASH') {
+      &cast((ref() ? $_ : \$_), $wiz, $depth + 1) for values %$var;
+     }
+     return $depth;
+    },
+    free => sub {
+     my ($var, $depth) = @_;
+     my $r = ref $var;
+     print "free $r at depth $depth\n";
+     ();
+    };
+
+    {
+     my %h = (
+      a => [ 1, 2 ],
+      b => { c => 3 }
+     );
+     cast %h, $wiz;
+    }
+
+When C<%h> goes out of scope, this prints something among the lines of :
+
+    free HASH at depth 0
+    free HASH at depth 1
+    free SCALAR at depth 2
+    free ARRAY at depth 1
+    free SCALAR at depth 3
+    free SCALAR at depth 3
+
+Of course, this example does nothing with the values that are added after the C<cast>.
 
-=head2 C<getsig>
+=head1 PERL MAGIC HISTORY
 
-    getsig $wiz
+The places where magic is invoked have changed a bit through perl history.
+Here is a little list of the most recent ones.
 
-This accessor returns the magic signature of this wizard.
+=over 4
 
-    # Get $wiz signature
-    my $sig = getsig $wiz;
+=item *
 
-=head2 C<cast>
+B<5.6.x>
 
-    cast [$@%&*]var, [$wiz|$sig], ...
+I<p14416> : 'copy' and 'dup' magic.
 
-This function associates C<$wiz> magic to the variable supplied, without overwriting any other kind of magic.
-You can also supply the numeric signature C<$sig> instead of C<$wiz>.
-It returns true on success or when C<$wiz> magic is already present, C<0> on error, and C<undef> when no magic corresponds to the given signature (in case C<$sig> was supplied).
-All extra arguments specified after C<$wiz> are passed to the private data constructor.
-If the variable isn't a hash, any C<uvar> callback of the wizard is safely ignored.
+=item *
 
-    # Casts $wiz onto $x. If $wiz isn't a signature, undef can't be returned.
-    my $x;
-    die 'error' unless cast $x, $wiz;
+B<5.8.9>
 
-The C<var> argument can be an array or hash value.
-Magic for those behaves like for any other scalar, except that it is dispelled when the entry is deleted from the container.
-For example, if you want to call C<POSIX::tzset> each time the C<'TZ'> environment variable is changed in C<%ENV>, you can use :
+I<p28160> : Integration of I<p25854> (see below).
 
-    use POSIX;
-    cast $ENV{TZ}, wizard set => sub { POSIX::tzset(); () };
+I<p32542> : Integration of I<p31473> (see below).
 
-If you want to overcome the possible deletion of the C<'TZ'> entry, you have no choice but to rely on C<store> uvar magic.
+=item *
 
-=head2 C<getdata>
+B<5.9.3>
 
-    getdata [$@%&*]var, [$wiz|$sig]
+I<p25854> : 'len' magic is no longer called when pushing an element into a magic array.
 
-This accessor fetches the private data associated with the magic C<$wiz> (or the signature C<$sig>) in the variable.
-C<undef> is returned when no such magic or data is found, or when C<$sig> does not represent a current valid magic object.
+I<p26569> : 'local' magic.
 
-    # Get the attached data.
-    my $data = getdata $x, $wiz or die 'no such magic or magic has no data';
+=item *
 
-=head2 C<dispell>
+B<5.9.5>
 
-    dispell [$@%&*]variable, [$wiz|$sig]
+I<p31064> : Meaningful 'uvar' magic.
 
-The exact opposite of L</cast> : it dissociates C<$wiz> magic from the variable.
-You can also pass the magic signature C<$sig> as the second argument.
-True is returned on success, C<0> on error or when no magic represented by C<$wiz> could be found in the variable, and C<undef> when no magic corresponds to the given signature (in case C<$sig> was supplied).
+I<p31473> : 'clear' magic was not invoked when undefining an array.
+The bug is fixed as of this version.
 
-    # Dispell now. If $wiz isn't a signature, undef can't be returned.
-    die 'no such magic or error' unless dispell $x, $wiz;
+=item *
+
+B<5.10.0>
+
+Since C<PERL_MAGIC_uvar> is uppercased, C<hv_magic_check()> triggers 'copy' magic on hash stores for (non-tied) hashes that also have 'uvar' magic.
+
+=item *
+
+B<5.11.x>
+
+I<p32969> : 'len' magic is no longer invoked when calling C<length> with a magical scalar.
+
+I<p34908> : 'len' magic is no longer called when pushing / unshifting an element into a magical array in void context.
+The C<push> part was already covered by I<p25854>.
+
+I<g9cdcb38b> : 'len' magic is called again when pushing into a magical array in non-void context.
+
+=back
 
 =head1 EXPORT
 
-The functions L</wizard>, L</gensig>, L</getsig>, L</cast>, L</getdata> and L</dispell> are only exported on request.
+The functions L</wizard>, L</cast>, L</getdata> and L</dispell> are only exported on request.
 All of them are exported by the tags C<':funcs'> and C<':all'>.
 
-The constants L</SIG_MIN>, L</SIG_MAX>, L</SIG_NBR>, L</MGf_COPY>, L</MGf_DUP>, L</MGf_LOCAL> and L</VMG_UVAR> are also only exported on request.
-They are all exported by the tags C<':consts'> and C<':all'>.
+All the constants are also only exported on request, either individually or by the tags C<':consts'> and C<':all'>.
 
 =cut
 
-use base qw/Exporter/;
+use base qw<Exporter>;
 
 our @EXPORT         = ();
 our %EXPORT_TAGS    = (
- 'funcs' =>  [ qw/wizard gensig getsig cast getdata dispell/ ],
- 'consts' => [
-               qw/SIG_MIN SIG_MAX SIG_NBR MGf_COPY MGf_DUP MGf_LOCAL VMG_UVAR/,
-               qw/VMG_COMPAT_ARRAY_PUSH_NOLEN VMG_COMPAT_ARRAY_UNSHIFT_NOLEN_VOID VMG_COMPAT_ARRAY_UNDEF_CLEAR VMG_COMPAT_SCALAR_LENGTH_NOLEN/,
-               qw/VMG_PERL_PATCHLEVEL/,
-               qw/VMG_THREADSAFE/,
-               qw/VMG_OP_INFO_NAME VMG_OP_INFO_OBJECT/
-             ]
+ 'funcs' =>  [ qw<wizard cast getdata dispell> ],
+ 'consts' => [ qw<
+   MGf_COPY MGf_DUP MGf_LOCAL VMG_UVAR
+   VMG_COMPAT_SCALAR_LENGTH_NOLEN
+   VMG_COMPAT_ARRAY_PUSH_NOLEN VMG_COMPAT_ARRAY_PUSH_NOLEN_VOID
+   VMG_COMPAT_ARRAY_UNSHIFT_NOLEN_VOID
+   VMG_COMPAT_ARRAY_UNDEF_CLEAR
+   VMG_COMPAT_HASH_DELETE_NOUVAR_VOID
+   VMG_COMPAT_GLOB_GET
+   VMG_PERL_PATCHLEVEL
+   VMG_THREADSAFE VMG_FORKSAFE
+   VMG_OP_INFO_NAME VMG_OP_INFO_OBJECT
+ > ],
 );
 our @EXPORT_OK      = map { @$_ } values %EXPORT_TAGS;
 $EXPORT_TAGS{'all'} = [ @EXPORT_OK ];
 
-END { _cleanup() }
-
 =head1 CAVEATS
 
-If you store a magic object in the private data slot, the magic won't be accessible by L</getdata> since it's not copied by assignation.
-The only way to address this would be to return a reference.
+In order to hook hash operations with magic, you need at least perl 5.10.0 (see L</VMG_UVAR>).
 
-If you define a wizard with a C<free> callback and cast it on itself, this destructor won't be called because the wizard will be destroyed first.
+If you want to store a magic object in the private data slot, you will not be able to recover the magic with L</getdata>, since magic is not copied by assignment.
+You can work around this gotcha by storing a reference to the magic object instead.
+
+If you define a wizard with a C<free> callback and cast it on itself, it results in a memory cycle, so this destructor will not be called when the wizard is freed.
 
 =head1 DEPENDENCIES
 
 L<perl> 5.8.
 
-L<Carp> (standard since perl 5), L<XSLoader> (standard since perl 5.006).
-
-Copy tests need L<Tie::Array> (standard since perl 5.005) and L<Tie::Hash> (since 5.002).
-
-Some uvar tests need L<Hash::Util::FieldHash> (standard since perl 5.009004).
+A C compiler.
+This module may happen to build with a C++ compiler as well, but don't rely on it, as no guarantee is made in this regard.
 
-Glob tests need L<Symbol> (standard since perl 5.002).
+L<Carp> (core since perl 5), L<XSLoader> (since 5.006).
 
-Threads tests need L<threads> and L<threads::shared>.
+Copy tests need L<Tie::Array> (core since perl 5.005) and L<Tie::Hash> (since 5.002).
+Some uvar tests need L<Hash::Util::FieldHash> (since 5.009004).
+Glob tests need L<Symbol> (since 5.002).
+Threads tests need L<threads> and L<threads::shared> (both since 5.007003).
 
 =head1 SEE ALSO
 
@@ -516,7 +676,8 @@ You can contact me by mail or on C<irc.perl.org> (vincent).
 
 =head1 BUGS
 
-Please report any bugs or feature requests to C<bug-variable-magic at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Variable-Magic>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
+Please report any bugs or feature requests to C<bug-variable-magic at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Variable-Magic>.
+I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
 
 =head1 SUPPORT
 
@@ -528,7 +689,7 @@ Tests code coverage report is available at L<http://www.profvince.com/perl/cover
 
 =head1 COPYRIGHT & LICENSE
 
-Copyright 2007-2009 Vincent Pit, all rights reserved.
+Copyright 2007,2008,2009,2010,2011,2012 Vincent Pit, all rights reserved.
 
 This program is free software; you can redistribute it and/or modify it
 under the same terms as Perl itself.