]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - lib/Variable/Magic.pm
Minor fixes in the global destruction comment
[perl/modules/Variable-Magic.git] / lib / Variable / Magic.pm
index 4359fef0976cc7c6b3ec1c4f4536a3259fad7f91..36559ac5fb4990238f5f3c4f8780a3becc11557d 100644 (file)
@@ -24,14 +24,29 @@ BEGIN {
 
 =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", because the 'banana' key doesn't exist in %h
+     $h{pear} = 1;           # "key pear stored in helem"
+    }
 
 =head1 DESCRIPTION
 
@@ -278,6 +293,8 @@ However, only the return value of the C<len> callback currently holds a meaning.
                      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 {
@@ -336,6 +353,48 @@ For example, if you want to call C<POSIX::tzset> each time the C<'TZ'> environme
 
 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]