Revision history for Variable-Magic
+0.02 2007-07-27 13:50 UTC
+ + Fix : In response to test report 548152 :
+ Newx() and SvMAGIC_set() not present on older perls.
+ + Fix : In response to test report 548275 :
+ Since perl 5.9.5, 'clear' magic is invoked when an array is
+ undefined (bug #43357). Moreover, 'len' magic is no longer
+ called by pushing an element since perl 5.9.3.
+ + Fix : Missing glob test in MANIFEST.
+
0.01 2007-07-25 16:15 UTC
First version, released on an unsuspecting world.
t/31-array.t
t/32-hash.t
t/33-code.t
+t/34-glob.t
t/boilerplate.t
t/kwalitee.t
t/pod-coverage.t
--- #YAML:1.0
name: Variable-Magic
-version: 0.01
+version: 0.02
abstract: Associate user-defined magic to variables from Perl.
license: perl
generated_by: ExtUtils::MakeMaker version 6.36
#include "perl.h"
#include "XSUB.h"
+/* --- Compatibility ------------------------------------------------------- */
+
+#ifndef Newx
+# define Newx(v, n, c) New(0, v, n, c)
+#endif
+
+#ifndef SvMAGIC_set
+# define SvMAGIC_set(sv, val) (SvMAGIC(sv) = (val))
+#endif
+
#define SIG_WIZ ((U16) (1u << 8 - 1))
#define R(S) fprintf(stderr, "R(" #S ") = %d\n", SvREFCNT(sv))
Variable::Magic - Associate user-defined magic to variables from Perl.
VERSION
- Version 0.01
+ Version 0.02
SYNOPSIS
use Variable::Magic qw/wizard cast dispell/;
"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 reset is a
- result of the undefine (e.g. for an array).
+ 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"
This last one can be considered as an object destructor. It happens
an unique numerical signature is attached to each kind of magic (i.e.
each set of callbacks for magic operations).
+PERL MAGIC HISTORY
+ 5.9.3
+ 'len' magic is no longer called when pushing an element into a magic
+ array.
+
+ 5.9.5
+ 'clear' magic wasn't invoked when undefining an array. The bug is fixed
+ as of this version.
+
CONSTANTS
"SIG_MIN"
The minimum integer used as a signature for user-defined magic.
=head1 VERSION
-Version 0.01
+Version 0.02
=cut
-our $VERSION = '0.01';
+our $VERSION = '0.02';
=head1 SYNOPSIS
=item C<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 reset is a result of the undefine (e.g. for an array).
+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 L<history|/PERL MAGIC HISTORY>).
=item C<free>
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).
+=head1 PERL MAGIC HISTORY
+
+=head2 B<5.9.3>
+
+=over 4
+
+=item 'len' magic is no longer called when pushing an element into a magic array.
+
+=back
+
+=head2 B<5.9.5>
+
+=over 4
+
+=item 'clear' magic wasn't invoked when undefining an array. The bug is fixed as of this version.
+
+=back
+
=head1 CONSTANTS
=head2 C<SIG_MIN>
ok(check(), 'array : assign new element');
push @a, 'x';
-++$x[1]; ++$x[2];
+++$x[1]; ++$x[2] unless $^V && $^V gt 5.9.2; # since 5.9.3
ok(check(), 'array : push');
pop @a;
{
my @b = @n;
-# cast @b, $wiz;
+ cast @b, $wiz;
}
-#++$x[4];
+++$x[4];
ok(check(), 'array : scope end');
undef @a;
+++$x[3] if $^V && $^V gt 5.9.4; # since 5.9.5 - see #43357
ok(check(), 'array : undef');
dispell @a, $wiz;
{
my %b = %n;
-# cast %b, $wiz;
+ cast %b, $wiz;
}
-#++$x[4];
+++$x[4];
ok(check(), 'hash : scope end');
undef %a;
--- /dev/null
+#!perl -T
+
+use Test::More;
+
+eval "use Symbol qw/gensym/";
+if ($@) {
+ plan skip_all => "Symbol::gensym required for testing magic for globs";
+} else {
+ plan tests => 7;
+}
+
+use Variable::Magic qw/wizard cast dispell/;
+
+my @c = (0) x 5;
+my @x = (0) x 5;
+
+sub check {
+ for (0 .. 4) { return 0 unless $c[$_] == $x[$_]; }
+ return 1;
+}
+
+my $i = -1;
+my $wiz = wizard get => sub { ++$c[0] },
+ set => sub { ++$c[1] },
+ len => sub { ++$c[2] },
+ clear => sub { ++$c[3] },
+ free => sub { ++$c[4] };
+ok(check(), 'glob : create wizard');
+
+local *a = gensym();
+
+cast *a, $wiz;
+ok(check(), 'glob : cast');
+
+local *b = *a;
+ok(check(), 'glob : assign to');
+
+*a = gensym();
+++$x[1];
+ok(check(), 'glob : assign');
+
+{
+ local *b = gensym();
+ cast *b, $wiz;
+}
+ok(check(), 'glob : scope end');
+
+undef *a;
+ok(check(), 'glob : undef');
+
+dispell *a, $wiz;
+ok(check(), 'glob : dispell');