]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - README
This is 0.34
[perl/modules/Variable-Magic.git] / README
diff --git a/README b/README
index 171a7ca2cfdc055fb271a679d72d6ecb4e74198f..c6f0d2005bb2b2c26682027cc974e770dc62f85e 100644 (file)
--- 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.34
 
 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
@@ -37,11 +52,12 @@ DESCRIPTION
 
     *   It doesn't replace the original semantics.
 
-        Magic callbacks trigger before the original action take place, and
-        can't prevent it to happen. This makes catching individual events
-        easier than with "tie", where you have to provide fallbacks methods
-        for all actions by usually inheriting from the correct "Tie::Std*"
-        class and overriding individual methods in your own class.
+        Magic callbacks usually trigger before the original action take
+        place, and can't prevent it to happen. This also makes catching
+        individual events easier than with "tie", where you have to provide
+        fallbacks methods for all actions by usually inheriting from the
+        correct "Tie::Std*" class and overriding individual methods in your
+        own class.
 
     *   It's type-agnostic.
 
@@ -92,8 +108,7 @@ DESCRIPTION
     *   "free"
 
         This one can be considered as an object destructor. It happens when
-        the variable goes out of scope (with the exception of global scope),
-        but not when it is undefined.
+        the variable goes out of scope, but not when it is undefined.
 
     *   "copy"
 
@@ -137,7 +152,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 +244,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
@@ -248,15 +270,15 @@ FUNCTIONS
     This function associates $wiz magic to the variable supplied, without
     overwriting any other kind of magic. You can also supply the numeric
     signature $sig instead of $wiz. It returns true on success or when $wiz
-    magic is already present, 0 on error, and "undef" when no magic
-    corresponds to the given signature (in case $sig was supplied). All
+    magic is already present, and croaks on error or when no magic
+    corresponds to the given signature (in case $sig was supplied). All
     extra arguments specified after $wiz are passed to the private data
-    constructor. If the variable isn't a hash, any "uvar" callback of the
-    wizard is safely ignored.
+    constructor in @_[1 .. @_-1]. If the variable isn't a hash, any "uvar"
+    callback of the wizard is safely ignored.
 
-        # Casts $wiz onto $x. If $wiz isn't a signature, undef can't be returned.
+        # Casts $wiz onto $x, and pass '1' to the data constructor.
         my $x;
-        die 'error' unless cast $x, $wiz;
+        cast $x, $wiz, 1;
 
     The "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
@@ -270,28 +292,73 @@ 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]
 
     This accessor fetches the private data associated with the magic $wiz
-    (or the signature $sig) in the variable. "undef" is returned when no
-    such magic or data is found, or when $sig does not represent a current
-    valid magic object.
+    (or the signature $sig) in the variable. It croaks when $wiz or $sig do
+    not represent a current valid magic object attached to the variable, and
+    returns "undef" when the wizard has no data constructor or when the data
+    is actually "undef".
 
-        # Get the attached data.
-        my $data = getdata $x, $wiz or die 'no such magic or magic has no data';
+        # Get the attached data, or undef if the wizard does not attach any.
+        my $data = getdata $x, $wiz;
 
   "dispell"
         dispell [$@%&*]variable, [$wiz|$sig]
 
     The exact opposite of "cast" : it dissociates $wiz magic from the
     variable. You can also pass the magic signature $sig as the second
-    argument. True is returned on success, 0 on error or when no magic
-    represented by $wiz could be found in the variable, and "undef" when no
-    magic corresponds to the given signature (in case $sig was supplied).
+    argument. This function returns true on success, 0 when no magic
+    represented by $wiz or $sig could be found in the variable, and croaks
+    if the supplied wizard or signature is invalid.
 
-        # Dispell now. If $wiz isn't a signature, undef can't be returned.
-        die 'no such magic or error' unless dispell $x, $wiz;
+        # Dispell now.
+        die 'no such magic in $x' unless dispell $x, $wiz;
 
 CONSTANTS
   "SIG_MIN"