From: Vincent Pit Date: Sun, 1 Mar 2009 13:44:01 +0000 (+0100) Subject: This is 0.32 X-Git-Tag: v0.32^0 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FVariable-Magic.git;a=commitdiff_plain;h=3c57941c660d64b4b3ad75b15d5afc8e9201f5d0 This is 0.32 --- diff --git a/Changes b/Changes index 4ad9adb..a94c094 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,15 @@ Revision history for Variable-Magic +0.32 2009-03-01 13:45 UTC + + Chg : dispell() and getdata() now croak when an invalid signature is + passed. + + Doc : More examples and a brand new synopsis. + + Fix : The signature is no longer stored in the mg_private member of + the MAGIC struct. This fixes possible clashes with magics from + other extensions. + + Fix : op info objects weren't blessed into the right class. + + Fix : Races when initializing the op names cache under threads. + 0.31 2009-02-19 23:50 UTC + Doc : A somewhat better introduction. The FUNCTION section was moved before CONSTANTS and HISTORY since it's more important. And diff --git a/META.yml b/META.yml index 1656441..6aecb32 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name: Variable-Magic -version: 0.31 +version: 0.32 abstract: Associate user-defined magic to variables from Perl. author: - Vincent Pit diff --git a/README b/README index 171a7ca..030eb08 100644 --- a/README +++ b/README @@ -2,17 +2,32 @@ NAME Variable::Magic - Associate user-defined magic to variables from Perl. VERSION - Version 0.31 + Version 0.32 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" + } DESCRIPTION Magic is Perl way of enhancing objects. This mechanism lets the user add @@ -25,7 +40,7 @@ DESCRIPTION variables. It's not surprising, as tied variables are implemented as a special kind of magic, just like any 'irregular' Perl variable : scalars like $!, $( or $^W, the %ENV and %SIG hashes, the @ISA array, "vec()" - and "substr()" lvalues, thread::shared variables... They all share the + and "substr()" lvalues, 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 @@ -83,11 +98,12 @@ DESCRIPTION * "clear" - This magic is invoked when the variable is reset, such as when an - array is emptied. Please note that this is different from undefining - the variable, even though the magic is called when the clearing is a - result of the undefine (e.g. for an array, but actually a bug - prevent it to work before perl 5.9.5 - see the history). + This magic is invoked when a container variable is reset, i.e. when + an array or a hash is emptied. Please note that this is different + from undefining the variable, even though the magic is called when + the clearing is a result of the undefine (e.g. for an array, but + actually a bug prevent it to work before perl 5.9.5 - see the + history). * "free" @@ -137,7 +153,10 @@ DESCRIPTION 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). + each set of callbacks for magic operations). At the C level, magic + tokens owned by magic created by this module have their "mg->mg_private" + field set to 0x3891 or 0x3892, so please don't use these magic (sic) + numbers in other extensions. FUNCTIONS "wizard" @@ -226,6 +245,10 @@ FUNCTIONS set => sub { print STDERR "set to ${$_[0]}\n" }, free => sub { print STDERR "${$_[0]} was deleted\n" } + Note that "free" callbacks are *never* called during global destruction, + as there's no way to ensure that the wizard and the "free" callback + weren't destroyed before the variable. + "gensig" With this tool, you can manually generate random magic signature between SIG_MIN and SIG_MAX inclusive. That's the way "wizard" creates them when @@ -270,6 +293,50 @@ FUNCTIONS If you want to overcome the possible deletion of the 'TZ' entry, you have no choice but to rely on "store" uvar magic. + "cast" can be called from any magical callback, and in particular from + "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 %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 "cast". + "getdata" getdata [$@%&*]var, [$wiz|$sig] diff --git a/lib/Variable/Magic.pm b/lib/Variable/Magic.pm index 59900d0..cc3bf4b 100644 --- a/lib/Variable/Magic.pm +++ b/lib/Variable/Magic.pm @@ -13,13 +13,13 @@ Variable::Magic - Associate user-defined magic to variables from Perl. =head1 VERSION -Version 0.31 +Version 0.32 =cut our $VERSION; BEGIN { - $VERSION = '0.31'; + $VERSION = '0.32'; } =head1 SYNOPSIS