]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Add a cookbook section
authorVincent Pit <vince@profvince.com>
Sun, 4 Oct 2009 15:54:49 +0000 (17:54 +0200)
committerVincent Pit <vince@profvince.com>
Sun, 4 Oct 2009 15:54:49 +0000 (17:54 +0200)
lib/Variable/Magic.pm

index 7928af0b8b4d4e77f2b8a5d7efd2c163a85b96c9..c651e09cae2314101e2e9456732434251c7f7318 100644 (file)
@@ -360,48 +360,6 @@ 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
@@ -500,6 +458,84 @@ Value to pass with C<op_info> to get the current op name in the magic callbacks.
 
 Value to pass with C<op_info> to get a C<B::OP> object representing the current op in the magic callbacks.
 
+=head1 COOKBOOK
+
+=head2 Associate an object to any perl variable
+
+This can be useful for passing user data through limited APIs.
+
+    {
+     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) {
+       &cast($var, $wiz);
+       $data = &getdata($var, $wiz);
+       die "Couldn't cast UserData magic onto the variable" unless defined $data;
+      }
+      $$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 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>.
+
 =head1 PERL MAGIC HISTORY
 
 The places where magic is invoked have changed a bit through perl history.