From: Vincent Pit Date: Sun, 4 Oct 2009 15:54:49 +0000 (+0200) Subject: Add a cookbook section X-Git-Tag: v0.38~1 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=commitdiff_plain;h=f5d5970869ec9d8a402c4cd7a480d5b526406055 Add a cookbook section --- diff --git a/lib/Variable/Magic.pm b/lib/Variable/Magic.pm index 7928af0..c651e09 100644 --- a/lib/Variable/Magic.pm +++ b/lib/Variable/Magic.pm @@ -360,48 +360,6 @@ For example, if you want to call C 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 uvar magic. -C can be called from any magical callback, and in particular from C. -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. - =head2 C getdata [$@%&*]var, $wiz @@ -500,6 +458,84 @@ Value to pass with C to get the current op name in the magic callbacks. Value to pass with C to get a C 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 can be called from any magical callback, and in particular from C. +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. + =head1 PERL MAGIC HISTORY The places where magic is invoked have changed a bit through perl history.