+ # 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" }
+
+Note that C<free> callbacks are I<never> called during global destruction, as there's no way to ensure that the wizard and the C<free> callback weren't destroyed before the variable.
+
+=cut
+
+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;
+}
+
+=head2 C<gensig>
+
+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.
+
+ # Generate a signature
+ my $sig = gensig;
+
+=head2 C<getsig>
+
+ getsig $wiz
+
+This accessor returns the magic signature of this wizard.
+
+ # Get $wiz signature
+ my $sig = getsig $wiz;
+
+=head2 C<cast>
+
+ cast [$@%&*]var, [$wiz|$sig], ...
+
+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, and croaks on error or when no magic corresponds to the given signature (in case a C<$sig> was supplied).
+All extra arguments specified after C<$wiz> are passed to the private data constructor in C<@_[1 .. @_-1]>.
+If the variable isn't a hash, any C<uvar> callback of the wizard is safely ignored.
+
+ # Casts $wiz onto $x, and pass '1' to the data constructor.
+ my $x;
+ cast $x, $wiz, 1;
+
+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 :
+
+ use POSIX;
+ cast $ENV{TZ}, wizard set => sub { POSIX::tzset(); () };
+
+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.
+
+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 will print 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<getdata>
+
+ getdata [$@%&*]var, [$wiz|$sig]
+
+This accessor fetches the private data associated with the magic C<$wiz> (or the signature C<$sig>) in the variable.
+It croaks when C<$wiz> or C<$sig> do 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.
+
+ # Get the attached data, or undef if the wizard does not attach any.
+ my $data = getdata $x, $wiz;
+
+=head2 C<dispell>
+
+ dispell [$@%&*]variable, [$wiz|$sig]
+
+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.
+This function returns true on success, C<0> when no magic represented by C<$wiz> or C<$sig> could be found in the variable, and croaks if the supplied wizard or signature is invalid.
+
+ # Dispell now.
+ die 'no such magic in $x' unless dispell $x, $wiz;
+