X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVariable%2FMagic.pm;h=772c8bd2cab857aa42115d6581ab796872fc475f;hb=refs%2Ftags%2Fv0.38;hp=fe96a192115b494725f779beb15230815adf41df;hpb=6a204757f3b9c5d10bc57e21cbb65c0e29688066;p=perl%2Fmodules%2FVariable-Magic.git
diff --git a/lib/Variable/Magic.pm b/lib/Variable/Magic.pm
index fe96a19..772c8bd 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.37
+Version 0.38
=cut
our $VERSION;
BEGIN {
- $VERSION = '0.37';
+ $VERSION = '0.38';
}
=head1 SYNOPSIS
@@ -208,8 +208,7 @@ BEGIN {
=head2 C
- wizard sig => ...,
- data => sub { ... },
+ wizard data => sub { ... },
get => sub { my ($ref, $data [, $op]) = @_; ... },
set => sub { my ($ref, $data [, $op]) = @_; ... },
len => sub { my ($ref, $data, $len [, $op]) = @_; ... ; return $newlen; },
@@ -237,6 +236,8 @@ The numerical signature.
If not specified or undefined, a random signature is generated.
If the signature matches an already defined magic, then the existant magic object is returned.
+This option is B and will be removed in december 2009.
+
=item *
C
@@ -324,6 +325,8 @@ That's the way L creates them when no signature is supplied.
# Generate a signature
my $sig = gensig;
+This function is B and will be removed in december 2009.
+
=head2 C
getsig $wiz
@@ -333,13 +336,14 @@ This accessor returns the magic signature of this wizard.
# Get $wiz signature
my $sig = getsig $wiz;
+This function is B and will be removed in december 2009.
+
=head2 C
- cast [$@%&*]var, [$wiz|$sig], ...
+ cast [$@%&*]var, $wiz, ...
This function associates C<$wiz> magic to the variable supplied, without overwriting any other kind of magic.
-You can also supply the numeric signature C<$sig> instead of C<$wiz>.
-It returns true on success or when C<$wiz> magic is already present, and croaks on error or when no magic corresponds to the given signature (in case a C<$sig> was supplied).
+It returns true on success or when C<$wiz> magic is already present, and croaks on error.
All extra arguments specified after C<$wiz> are passed to the private data constructor in C<@_[1 .. @_-1]>.
If the variable isn't a hash, any C callback of the wizard is safely ignored.
@@ -356,65 +360,22 @@ 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|$sig]
+ getdata [$@%&*]var, $wiz
-This accessor fetches the private data associated with the magic C<$wiz> (or the signature C<$sig>) in the variable.
-It croaks when C<$wiz> or C<$sig> do not represent a valid magic object, and returns an empty list if no such magic is attached to the variable or when the wizard has no data constructor.
+This accessor fetches the private data associated with the magic C<$wiz> in the variable.
+It croaks when C<$wiz> do not represent a valid magic object, and returns an empty list if no such magic is attached to the variable or when the wizard has no data constructor.
# Get the attached data, or undef if the wizard does not attach any.
my $data = getdata $x, $wiz;
=head2 C
- dispell [$@%&*]variable, [$wiz|$sig]
+ dispell [$@%&*]variable, $wiz
The exact opposite of L : it dissociates C<$wiz> magic from the variable.
-You can also pass the magic signature C<$sig> as the second argument.
-This function returns true on success, C<0> when no magic represented by C<$wiz> or C<$sig> could be found in the variable, and croaks if the supplied wizard or signature is invalid.
+This function returns true on success, C<0> when no magic represented by C<$wiz> could be found in the variable, and croaks if the supplied wizard is invalid.
# Dispell now.
die 'no such magic in $x' unless dispell $x, $wiz;
@@ -425,14 +386,20 @@ This function returns true on success, C<0> when no magic represented by C<$wiz>
The minimum integer used as a signature for user-defined magic.
+This constant is B and will be removed in december 2009.
+
=head2 C
The maximum integer used as a signature for user-defined magic.
+This constant is B and will be removed in december 2009.
+
=head2 C
SIG_NBR = SIG_MAX - SIG_MIN + 1
+This constant is B and will be removed in december 2009.
+
=head2 C
Evaluates to true iff the 'copy' magic is available.
@@ -491,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.