Hello community,

here is the log from the commit of package perl-Variable-Magic for 
openSUSE:Factory checked in at 2015-07-23 15:22:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Variable-Magic (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Variable-Magic.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Variable-Magic"

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Variable-Magic/perl-Variable-Magic.changes  
2015-04-18 10:41:10.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Variable-Magic.new/perl-Variable-Magic.changes 
    2015-07-23 15:23:00.000000000 +0200
@@ -1,0 +2,16 @@
+Wed Jul 22 09:30:21 UTC 2015 - [email protected]
+
+- updated to 0.58
+   see /usr/share/doc/packages/perl-Variable-Magic/Changes
+
+  0.58    2015-07-21 16:00 UTC
+          + Add : If a non-len magic callback returns a reference, it will now
+                  only be freed at the end of the statement that caused the
+                  magic to trigger. This allows the user to attach free magic
+                  (or a plain destructor) to a token returned from the 
callbacks
+                  in order to defer an action after the magic is processed by
+                  perl.
+          + Fix : Test failures of threads tests on systems with harsh resource
+                  constraints causing the threads to exit() during run.
+
+-------------------------------------------------------------------

Old:
----
  Variable-Magic-0.57.tar.gz

New:
----
  Variable-Magic-0.58.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Variable-Magic.spec ++++++
--- /var/tmp/diff_new_pack.yMBkgX/_old  2015-07-23 15:23:00.000000000 +0200
+++ /var/tmp/diff_new_pack.yMBkgX/_new  2015-07-23 15:23:00.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Variable-Magic
-Version:        0.57
+Version:        0.58
 Release:        0
 %define cpan_name Variable-Magic
 Summary:        Associate user-defined magic to variables from Perl

++++++ Variable-Magic-0.57.tar.gz -> Variable-Magic-0.58.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/Changes 
new/Variable-Magic-0.58/Changes
--- old/Variable-Magic-0.57/Changes     2015-04-17 16:57:18.000000000 +0200
+++ new/Variable-Magic-0.58/Changes     2015-07-21 17:41:49.000000000 +0200
@@ -1,5 +1,15 @@
 Revision history for Variable-Magic
 
+0.58    2015-07-21 16:00 UTC
+        + Add : If a non-len magic callback returns a reference, it will now
+                only be freed at the end of the statement that caused the
+                magic to trigger. This allows the user to attach free magic
+                (or a plain destructor) to a token returned from the callbacks
+                in order to defer an action after the magic is processed by
+                perl.
+        + Fix : Test failures of threads tests on systems with harsh resource
+                constraints causing the threads to exit() during run.
+
 0.57    2015-04-17 15:20 UTC
         + Chg : The new environment variable to enable thread tests on older
                 perls is PERL_FORCE_TEST_THREADS. Note that this variable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/MANIFEST 
new/Variable-Magic-0.58/MANIFEST
--- old/Variable-Magic-0.57/MANIFEST    2015-03-28 01:38:33.000000000 +0100
+++ new/Variable-Magic-0.58/MANIFEST    2015-07-21 17:35:40.000000000 +0200
@@ -39,6 +39,7 @@
 t/35-stash.t
 t/40-threads.t
 t/41-clone.t
+t/50-return.t
 t/80-leaks.t
 t/lib/Test/Leaner.pm
 t/lib/VPIT/TestHelpers.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/META.json 
new/Variable-Magic-0.58/META.json
--- old/Variable-Magic-0.57/META.json   2015-04-17 16:59:24.000000000 +0200
+++ new/Variable-Magic-0.58/META.json   2015-07-21 17:42:56.000000000 +0200
@@ -4,7 +4,7 @@
       "Vincent Pit <[email protected]>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter 
version 2.150001",
+   "generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter 
version 2.150005",
    "license" : [
       "perl_5"
    ],
@@ -66,5 +66,6 @@
          "url" : 
"http://git.profvince.com/?p=perl%2Fmodules%2FVariable-Magic.git";
       }
    },
-   "version" : "0.57"
+   "version" : "0.58",
+   "x_serialization_backend" : "JSON::PP version 2.27300"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/META.yml 
new/Variable-Magic-0.58/META.yml
--- old/Variable-Magic-0.57/META.yml    2015-04-17 16:59:24.000000000 +0200
+++ new/Variable-Magic-0.58/META.yml    2015-07-21 17:42:55.000000000 +0200
@@ -20,7 +20,7 @@
   Config: '0'
   ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 
2.150001'
+generated_by: 'ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter 
version 2.150005'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -41,4 +41,5 @@
   homepage: http://search.cpan.org/dist/Variable-Magic/
   license: http://dev.perl.org/licenses/
   repository: http://git.profvince.com/?p=perl%2Fmodules%2FVariable-Magic.git
-version: '0.57'
+version: '0.58'
+x_serialization_backend: 'CPAN::Meta::YAML version 0.016'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/Magic.xs 
new/Variable-Magic-0.58/Magic.xs
--- old/Variable-Magic-0.57/Magic.xs    2015-04-14 19:00:58.000000000 +0200
+++ new/Variable-Magic-0.58/Magic.xs    2015-07-21 17:35:40.000000000 +0200
@@ -488,9 +488,8 @@
 
 /* --- Error messages ------------------------------------------------------ */
 
-static const char vmg_invalid_wiz[]    = "Invalid wizard object";
-static const char vmg_wrongargnum[]    = "Wrong number of arguments";
-static const char vmg_argstorefailed[] = "Error while storing arguments";
+static const char vmg_invalid_wiz[] = "Invalid wizard object";
+static const char vmg_wrongargnum[] = "Wrong number of arguments";
 
 /* --- Context-safe global data -------------------------------------------- */
 
@@ -1246,11 +1245,18 @@
  svr = POPs;
  if (SvOK(svr))
   ret = (int) SvIV(svr);
+ if (SvROK(svr))
+  SvREFCNT_inc(svr);
+ else
+  svr = NULL;
  PUTBACK;
 
  FREETMPS;
  LEAVE;
 
+ if (svr && !SvTEMP(svr))
+  sv_2mortal(svr);
+
  if (chain) {
   vmg_dispell_guard_new(*chain);
   *chain = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/README 
new/Variable-Magic-0.58/README
--- old/Variable-Magic-0.57/README      2015-04-17 16:59:24.000000000 +0200
+++ new/Variable-Magic-0.58/README      2015-07-21 17:42:56.000000000 +0200
@@ -2,7 +2,7 @@
     Variable::Magic - Associate user-defined magic to variables from Perl.
 
 VERSION
-    Version 0.57
+    Version 0.58
 
 SYNOPSIS
         use Variable::Magic qw<wizard cast VMG_OP_INFO_NAME>;
@@ -265,10 +265,17 @@
         Both result in a small performance hit, but just getting the name is
         lighter than getting the op object.
 
-        These callbacks are executed in scalar context and are expected to
-        return an integer, which is then passed straight to the perl magic
-        API. However, only the return value of the *len* magic callback
-        currently holds a meaning.
+        These callbacks are always executed in scalar context. The returned
+        value is coerced into a signed integer, which is then passed
+        straight to the perl magic API. However, note that perl currently
+        only cares about the return value of the *len* magic callback and
+        ignores all the others. Starting with Variable::Magic 0.58, a
+        reference returned from a non-*len* magic callback will not be
+        destroyed immediately but will be allowed to survive until the end
+        of the statement that triggered the magic. This lets you use this
+        return value as a token for triggering a destructor after the
+        original magic action takes place. You can see an example of this
+        technique in the cookbook.
 
     Each callback can be specified as :
 
@@ -501,6 +508,45 @@
     Of course, this example does nothing with the values that are added
     after the "cast".
 
+  Delayed magic actions
+    Starting with Variable::Magic 0.58, the return value of the magic
+    callbacks can be used to delay the action until after the original
+    action takes place :
+
+        my $delayed;
+        my $delayed_aux = wizard(
+         data => sub { $_[1] },
+         free => sub {
+          my ($target) = $_[1];
+          my $target_data = &getdata($target, $delayed);
+          local $target_data->{guard} = 1;
+          if (ref $target eq 'SCALAR') {
+           my $orig = $$target;
+           $$target = $target_data->{mangler}->($orig);
+          }
+          return;
+         },
+        );
+        $delayed = wizard(
+         data => sub {
+          return +{ guard => 0, mangler => $_[1] };
+         },
+         set  => sub {
+          return if $_[1]->{guard};
+          my $token;
+          cast $token, $delayed_aux, $_[0];
+          return \$token;
+         },
+        );
+        my $x = 1;
+        cast $x, $delayed => sub { $_[0] * 2 };
+        $x = 2;
+        # $x is now 4
+        # But note that the delayed action only takes place at the end of the
+        # current statement :
+        my @y = ($x = 5, $x);
+        # $x is now 10, but @y is (5, 5)
+
 PERL MAGIC HISTORY
     The places where magic is invoked have changed a bit through perl
     history. Here is a little list of the most recent ones.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/lib/Variable/Magic.pm 
new/Variable-Magic-0.58/lib/Variable/Magic.pm
--- old/Variable-Magic-0.57/lib/Variable/Magic.pm       2015-04-17 
16:57:39.000000000 +0200
+++ new/Variable-Magic-0.58/lib/Variable/Magic.pm       2015-07-21 
17:35:40.000000000 +0200
@@ -11,13 +11,13 @@
 
 =head1 VERSION
 
-Version 0.57
+Version 0.58
 
 =cut
 
 our $VERSION;
 BEGIN {
- $VERSION = '0.57';
+ $VERSION = '0.58';
 }
 
 =head1 SYNOPSIS
@@ -309,8 +309,12 @@
 
 Both result in a small performance hit, but just getting the name is lighter 
than getting the op object.
 
-These callbacks are executed in scalar context and are expected to return an 
integer, which is then passed straight to the perl magic API.
-However, only the return value of the I<len> magic callback currently holds a 
meaning.
+These callbacks are always executed in scalar context.
+The returned value is coerced into a signed integer, which is then passed 
straight to the perl magic API.
+However, note that perl currently only cares about the return value of the 
I<len> magic callback and ignores all the others.
+Starting with Variable::Magic 0.58, a reference returned from a non-I<len> 
magic callback will not be destroyed immediately but will be allowed to survive 
until the end of the statement that triggered the magic.
+This lets you use this return value as a token for triggering a destructor 
after the original magic action takes place.
+You can see an example of this technique in the L<cookbook|/COOKBOOK>.
 
 =back
 
@@ -577,6 +581,44 @@
 
 Of course, this example does nothing with the values that are added after the 
C<cast>.
 
+=head2 Delayed magic actions
+
+Starting with Variable::Magic 0.58, the return value of the magic callbacks 
can be used to delay the action until after the original action takes place :
+
+    my $delayed;
+    my $delayed_aux = wizard(
+     data => sub { $_[1] },
+     free => sub {
+      my ($target) = $_[1];
+      my $target_data = &getdata($target, $delayed);
+      local $target_data->{guard} = 1;
+      if (ref $target eq 'SCALAR') {
+       my $orig = $$target;
+       $$target = $target_data->{mangler}->($orig);
+      }
+      return;
+     },
+    );
+    $delayed = wizard(
+     data => sub {
+      return +{ guard => 0, mangler => $_[1] };
+     },
+     set  => sub {
+      return if $_[1]->{guard};
+      my $token;
+      cast $token, $delayed_aux, $_[0];
+      return \$token;
+     },
+    );
+    my $x = 1;
+    cast $x, $delayed => sub { $_[0] * 2 };
+    $x = 2;
+    # $x is now 4
+    # But note that the delayed action only takes place at the end of the
+    # current statement :
+    my @y = ($x = 5, $x);
+    # $x is now 10, but @y is (5, 5)
+
 =head1 PERL MAGIC HISTORY
 
 The places where magic is invoked have changed a bit through perl history.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/09-load-threads.t 
new/Variable-Magic-0.58/t/09-load-threads.t
--- old/Variable-Magic-0.57/t/09-load-threads.t 2015-04-16 21:25:01.000000000 
+0200
+++ new/Variable-Magic-0.58/t/09-load-threads.t 2015-07-21 17:24:34.000000000 
+0200
@@ -29,9 +29,7 @@
 
 my $could_not_create_thread = 'Could not create thread';
 
-use Test::Leaner (
- tests => 1 + (2 + 2 * 2) + 6 + (2 * 4 + 1) * 2 + (4 + 1) + (6 + 1) + 1
-);
+use Test::Leaner;
 
 sub is_loaded {
  my ($affirmative, $desc) = @_;
@@ -178,10 +176,19 @@
   cond_broadcast $locks_down[$id];
  }
 
- {
+ LOCK: {
   lock $locks_up[$id];
-  cond_wait $locks_up[$id] until $locks_up[$id] == $peers;
+  my $timeout = time() + 10;
+  until ($locks_up[$id] == $peers) {
+   if (cond_timedwait $locks_up[$id], $timeout) {
+    last LOCK;
+   } else {
+    return 0;
+   }
+  }
  }
+
+ return 1;
 }
 
 sub sync_slave {
@@ -197,6 +204,8 @@
   $locks_up[$id]++;
   cond_signal $locks_up[$id];
  }
+
+ return 1;
 }
 
 for my $first_thread_ends_first (0, 1) {
@@ -238,7 +247,7 @@
 
    is_loaded 1, "$here, end";
 
-   return;
+   return 1;
   });
 
   skip "$could_not_create_thread (parallel 1)" => (4 * 2) unless defined $thr1;
@@ -263,7 +272,7 @@
 
    is_loaded 1, "$here, end";
 
-   return;
+   return 1;
   });
 
   sync_master($_) for 0 .. 5;
@@ -344,9 +353,6 @@
 # Test clone outliving its parent
 
 SKIP: {
- my $kid_tid;
- share($kid_tid);
-
  my $kid_done;
  share($kid_done);
 
@@ -354,11 +360,11 @@
   my $here = 'outliving clone, parent thread';
   is_loaded 0, "$here, beginning";
 
-  my $no_kid;
-
   do_load;
   is_loaded 1, "$here, after loading";
 
+  my $kid_tid;
+
   SKIP: {
    my $kid = spawn(sub {
     my $here = 'outliving clone, child thread';
@@ -366,52 +372,40 @@
     is_loaded 1, "$here, beginning";
 
     {
-     lock $kid_tid;
-     $kid_tid = threads->tid();
-     cond_signal $kid_tid;
-    }
-
-    is_loaded 1, "$here, kid tid was communicated";
-
-    {
      lock $kid_done;
      cond_wait $kid_done until $kid_done;
     }
 
     is_loaded 1, "$here, end";
 
-    return;
+    return 1;
    });
 
-   unless (defined $kid) {
-    $no_kid = 1;
-    skip "$could_not_create_thread (outliving clone child)" => 3;
+   if (defined $kid) {
+    $kid_tid = $kid->tid;
+   } else {
+    $kid_tid = 0;
+    skip "$could_not_create_thread (outliving clone child)" => 2;
    }
   }
 
   is_loaded 1, "$here, end";
 
-  return $no_kid;
+  return $kid_tid;
  });
 
- skip "$could_not_create_thread (outliving clone parent)" => (3 + 3)
+ skip "$could_not_create_thread (outliving clone parent)" => (3 + 2)
                                                          unless defined 
$parent;
 
- my $no_kid = $parent->join;
+ my $kid_tid = $parent->join;
  if (my $err = $parent->error) {
   die $err;
  }
 
- unless ($no_kid) {
-  my $tid = do {
-   lock $kid_tid;
-   cond_wait $kid_tid until defined $kid_tid;
-   $kid_tid;
-  };
-
-  my $kid = threads->object($tid);
+ if ($kid_tid) {
+  my $kid = threads->object($kid_tid);
   if (defined $kid) {
-   {
+   if ($kid->is_running) {
     lock $kid_done;
     $kid_done = 1;
     cond_signal $kid_done;
@@ -426,3 +420,5 @@
 
 do_load;
 is_loaded 1, 'main body, loaded at end';
+
+done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/18-opinfo.t 
new/Variable-Magic-0.58/t/18-opinfo.t
--- old/Variable-Magic-0.57/t/18-opinfo.t       2014-10-21 00:10:58.000000000 
+0200
+++ new/Variable-Magic-0.58/t/18-opinfo.t       2015-07-20 20:00:45.000000000 
+0200
@@ -50,10 +50,13 @@
 
 our $done;
 
+my $OP_INFO_NAME   = VMG_OP_INFO_NAME;
+my $OP_INFO_OBJECT = VMG_OP_INFO_OBJECT;
+
 for (@tests) {
  my ($key, $var, $init, $test, $exp) = @$_;
 
- for my $op_info (VMG_OP_INFO_NAME, VMG_OP_INFO_OBJECT) {
+ for my $op_info ($OP_INFO_NAME, $OP_INFO_OBJECT) {
   my $wiz;
 
   # We must test for the $op correctness inside the callback because, if we
@@ -64,9 +67,9 @@
     return if $done;
     my $op = $_[-1];
     my $desc = "$key magic with op_info == $op_info";
-    if ($op_info == VMG_OP_INFO_NAME) {
+    if ($op_info == $OP_INFO_NAME) {
      is $op, $exp->[0], "$desc gets the right op info";
-    } elsif ($op_info == VMG_OP_INFO_OBJECT) {
+    } elsif ($op_info == $OP_INFO_OBJECT) {
      isa_ok $op, $exp->[1], $desc;
      is $op->name, $exp->[0], "$desc gets the right op info";
     } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/40-threads.t 
new/Variable-Magic-0.58/t/40-threads.t
--- old/Variable-Magic-0.57/t/40-threads.t      2015-04-14 18:58:11.000000000 
+0200
+++ new/Variable-Magic-0.58/t/40-threads.t      2015-07-21 00:34:26.000000000 
+0200
@@ -102,7 +102,8 @@
    is $c, 1,  "get in thread $tid after dispell doesn't trigger magic";
   }
  }
- return; # Ugly if not here
+
+ return 1;
 }
 
 for my $dispell (1, 0) {
@@ -111,11 +112,16 @@
   $destroyed = 0;
  }
 
+ my $completed = 0;
+
  my @threads = map spawn(\&try, $dispell, $_), ('name') x 2, ('object') x 2;
- $_->join for @threads;
+ for my $thr (@threads) {
+  my $res = $thr->join;
+  $completed += $res if defined $res;
+ }
 
  {
   lock $destroyed;
-  is $destroyed, (1 - $dispell) * 4, 'destructors';
+  is $destroyed, (1 - $dispell) * $completed, 'destructors';
  }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/41-clone.t 
new/Variable-Magic-0.58/t/41-clone.t
--- old/Variable-Magic-0.57/t/41-clone.t        2015-04-14 18:39:50.000000000 
+0200
+++ new/Variable-Magic-0.58/t/41-clone.t        2015-07-21 00:34:26.000000000 
+0200
@@ -102,7 +102,7 @@
   }
  }
 
- return;
+ return 1;
 }
 
 my $wiz_name = spawn_wiz VMG_OP_INFO_NAME;
@@ -119,16 +119,21 @@
    $destroyed = 0;
   }
 
+  my $completed = 0;
+
   my @threads = map spawn(\&try, $dispell, $wiz), 1 .. 2;
-  $_->join for @threads;
+  for my $thr (@threads) {
+   my $res = $thr->join;
+   $completed += $res if defined $res;
+  }
 
   {
    lock $c;
-   is $c, 2, "get triggered twice";
+   is $c, $completed, "get triggered twice";
   }
   {
    lock $destroyed;
-   is $destroyed, (1 - $dispell) * 2, 'destructors';
+   is $destroyed, (1 - $dispell) * $completed, 'destructors';
   }
  }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/50-return.t 
new/Variable-Magic-0.58/t/50-return.t
--- old/Variable-Magic-0.57/t/50-return.t       1970-01-01 01:00:00.000000000 
+0100
+++ new/Variable-Magic-0.58/t/50-return.t       2015-07-20 19:44:01.000000000 
+0200
@@ -0,0 +1,195 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Variable::Magic qw<wizard cast dispell getdata>;
+
+use Test::More tests => 3 * 11;
+
+our $destroyed;
+
+my $destructor = wizard free => sub { ++$destroyed; return };
+
+{
+ my $increment;
+
+ my $increment_aux = wizard(
+  data => sub { $_[1] },
+  free => sub {
+   my ($target) = $_[1];
+   my $target_data = &getdata($target, $increment);
+   local $target_data->{guard} = 1;
+   ++$$target;
+   return;
+  },
+ );
+
+ $increment = wizard(
+  data => sub {
+   return +{ guard => 0 };
+  },
+  set  => sub {
+   return if $_[1]->{guard};
+   my $token;
+   cast $token, $increment_aux, $_[0];
+   return \$token;
+  },
+ );
+
+ local $destroyed = 0;
+
+ {
+  my $x = 0;
+
+  cast $x, $destructor;
+
+  {
+   cast $x, $increment;
+   is $x, 0;
+   $x = 1;
+   is $x, 2;
+   $x = 123;
+   is $x, 124;
+   $x = -5;
+   is $x, -4;
+   $x = 27, is($x, 27);
+   is $x, 28;
+   my @y = ($x = -13, $x);
+   is $x, -12;
+   is "@y", '-13 -13';
+  }
+
+  dispell $x, $increment;
+
+  $x = 456;
+  is $x, 456;
+
+  is $destroyed, 0;
+ }
+
+ is $destroyed, 1;
+}
+
+{
+ my $locker;
+
+ my $locker_aux = wizard(
+  data => sub { $_[1] },
+  free => sub {
+   my ($target) = $_[1];
+   my $target_data = &getdata($target, $locker);
+   local $target_data->{guard} = 1;
+   $$target = $target_data->{value};
+   return;
+  },
+ );
+
+ $locker = wizard(
+  data => sub {
+   return +{ guard => 0, value => $_[1] };
+  },
+  set  => sub {
+   return if $_[1]->{guard};
+   my $token;
+   cast $token, $locker_aux, $_[0];
+   return \$token;
+  },
+ );
+
+ local $destroyed = 0;
+
+ {
+  my $x = 0;
+
+  cast $x, $destructor;
+
+  {
+   cast $x, $locker, 999;
+   is $x, 0;
+   $x = 1;
+   is $x, 999;
+   $x = 123;
+   is $x, 999;
+   $x = -5;
+   is $x, 999;
+   $x = 27, is($x, 27);
+   is $x, 999;
+   my @y = ($x = -13, $x);
+   is $x, 999;
+   is "@y", '-13 -13';
+  }
+
+  dispell $x, $locker;
+
+  $x = 456;
+  is $x, 456;
+
+  is $destroyed, 0;
+ }
+
+ is $destroyed, 1;
+}
+
+{
+ my $delayed;
+
+ my $delayed_aux = wizard(
+  data => sub { $_[1] },
+  free => sub {
+   my ($target) = $_[1];
+   my $target_data = &getdata($target, $delayed);
+   local $target_data->{guard} = 1;
+   if (ref $target eq 'SCALAR') {
+    my $orig = $$target;
+    $$target = $target_data->{mangler}->($orig);
+   }
+   return;
+  },
+ );
+
+ $delayed = wizard(
+  data => sub {
+   return +{ guard => 0, mangler => $_[1] };
+  },
+  set  => sub {
+   return if $_[1]->{guard};
+   my $token;
+   cast $token, $delayed_aux, $_[0];
+   return \$token;
+  },
+ );
+
+ local $destroyed = 0;
+
+ {
+  my $x = 0;
+
+  cast $x, $destructor;
+
+  {
+   cast $x, $delayed => sub { $_[0] * 2 };
+   is $x, 0;
+   $x = 1;
+   is $x, 2;
+   $x = 123;
+   is $x, 246;
+   $x = -5;
+   is $x, -10;
+   $x = 27, is($x, 27);
+   is $x, 54;
+   my @y = ($x = -13, $x);
+   is $x, -26;
+   is "@y", '-13 -13';
+  }
+
+  dispell $x, $delayed;
+
+  $x = 456;
+  is $x, 456;
+
+  is $destroyed, 0;
+ }
+
+ is $destroyed, 1;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/80-leaks.t 
new/Variable-Magic-0.58/t/80-leaks.t
--- old/Variable-Magic-0.57/t/80-leaks.t        2014-10-20 23:23:19.000000000 
+0200
+++ new/Variable-Magic-0.58/t/80-leaks.t        2015-07-20 18:44:26.000000000 
+0200
@@ -3,9 +3,15 @@
 use strict;
 use warnings;
 
-use Test::More tests => 11;
+use Variable::Magic qw<wizard cast getdata dispell MGf_LOCAL VMG_UVAR>;
 
-use Variable::Magic qw<wizard cast getdata>;
+use Test::More;
+
+BEGIN {
+ my $tests = 11;
+ $tests += 4 * (4 + (MGf_LOCAL ? 1 : 0) + (VMG_UVAR ? 4 : 0));
+ plan tests => $tests;
+}
 
 our $destroyed;
 
@@ -89,3 +95,69 @@
 
  is $destroyed, 1;
 }
+
+# Test destruction of returned values
+
+my @methods = qw<get set clear free>;
+push @methods, 'local' if MGf_LOCAL;
+push @methods, qw<fetch store exists delete> if VMG_UVAR;
+
+my %init = (
+ scalar_lexical => 'my $x = 1; cast $x, $w',
+ scalar_global  => 'our $X; local $X = 1; cast $X, $w',
+ array          => 'my @a = (1); cast @a, $w',
+ hash           => 'my %h = (a => 1); cast %h, $w',
+);
+
+my %type;
+$type{$_} = 'scalar_lexical' for qw<get set free>;
+$type{$_} = 'scalar_global'  for qw<local>;
+$type{$_} = 'array'          for qw<clear>;
+$type{$_} = 'hash'           for qw<fetch store exists delete>;
+
+sub void { }
+
+my %trigger = (
+ get    => 'my $y = $x',
+ set    => '$x = 2',
+ clear  => '@a = ()',
+ free   => 'void()',
+ local  => 'local $X = 2',
+ fetch  => 'my $v = $h{a}',
+ store  => '$h{a} = 2',
+ exists => 'my $e = exists $h{a}',
+ delete => 'my $d = delete $h{a}',
+);
+
+for my $meth (@methods) {
+ local $destroyed = 0;
+
+ {
+  my $w = wizard $meth => sub { return D->new };
+
+  my $init    = $init{$type{$meth}};
+  my $trigger = $trigger{$meth};
+  my $deinit  = '';
+
+  if ($meth eq 'free') {
+   $init   = "{\n$init";
+   $deinit = '}';
+  }
+
+  my $code = join ";\n", grep length, (
+   $init,
+   'is $destroyed, 0, "return from $meth, before trigger"',
+   $trigger . ', is($destroyed, 0, "return from $meth, after trigger")',
+   $deinit,
+   'is $destroyed, 1, "return from $meth, after trigger"',
+  );
+
+  {
+   local $@;
+   eval $code;
+   die $@ if $@;
+  }
+
+  is $destroyed, 1, "return from $meth, end";
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Variable-Magic-0.57/t/lib/VPIT/TestHelpers.pm 
new/Variable-Magic-0.58/t/lib/VPIT/TestHelpers.pm
--- old/Variable-Magic-0.57/t/lib/VPIT/TestHelpers.pm   2015-04-14 
19:05:51.000000000 +0200
+++ new/Variable-Magic-0.58/t/lib/VPIT/TestHelpers.pm   2015-07-21 
00:33:52.000000000 +0200
@@ -600,6 +600,18 @@
 
 =back
 
+=item *
+
+Notes :
+
+=over 8
+
+=item -
+
+C<< exit => 'threads_only' >> is passed to C<< threads->import >>.
+
+=back
+
 =back
 
 =cut
@@ -644,7 +656,9 @@
   die "$test_module was loaded too soon" if defined $test_module;
  }
 
- load_or_skip_all 'threads',         $force ? '0' : '1.67', [ ];
+ load_or_skip_all 'threads',         $force ? '0' : '1.67', [
+  exit => 'threads_only',
+ ];
  load_or_skip_all 'threads::shared', $force ? '0' : '1.14', [ ];
 
  diag "Threads testing forced by \$ENV{$force_var}" if $force;
@@ -672,7 +686,18 @@
 
 Import :
 
-    use VPIT::TestHelpers 'usleep'
+    use VPIT::TestHelpers 'usleep' => [ @impls ];
+
+where :
+
+=over 8
+
+=item -
+
+C<@impls> is the list of desired implementations (which may be 
C<'Time::HiRes'>, C<'select'> or C<'sleep'>), in the order they should be 
checked.
+When the list is empty, it defaults to all of them.
+
+=back
 
 =item *
 
@@ -695,20 +720,60 @@
 =cut
 
 sub init_usleep {
- my $usleep;
+ my (@impls) = @_;
 
- if (do { local $@; eval { require Time::HiRes; 1 } }) {
-  defined and diag "Using usleep() from Time::HiRes $_"
+ my %impls = (
+  'Time::HiRes' => sub {
+   if (do { local $@; eval { require Time::HiRes; 1 } }) {
+    defined and diag "Using usleep() from Time::HiRes $_"
                                                       for 
$Time::HiRes::VERSION;
-  $usleep = \&Time::HiRes::usleep;
- } else {
-  diag 'Using fallback usleep()';
-  $usleep = sub {
-   my $s = int($_[0] / 1e6);
-   sleep $s if $s;
-  };
+    return \&Time::HiRes::usleep;
+   } else {
+    return undef;
+   }
+  },
+  'select' => sub {
+   if ($Config::Config{d_select}) {
+    diag 'Using select()-based fallback usleep()';
+    return sub ($) {
+     my $s = $_[0];
+     my $r = 0;
+     while ($s > 0) {
+      my ($found, $t) = select(undef, undef, undef, $s / 1e6);
+      last unless defined $t;
+      $t  = int($t * 1e6);
+      $s -= $t;
+      $r += $t;
+     }
+     return $r;
+    };
+   } else {
+    return undef;
+   }
+  },
+  'sleep' => sub {
+   diag 'Using sleep()-based fallback usleep()';
+   return sub ($) {
+    my $ms = int $_[0];
+    my $s  = int($ms / 1e6) + ($ms % 1e6 == 0 ? 0 : 1);
+    my $t  = sleep $s;
+    return $t * 1e6;
+   };
+  },
+ );
+
+ @impls = qw<Time::HiRes select sleep> unless @impls;
+
+ my $usleep;
+ for my $impl (@impls) {
+  next unless defined $impl and $impls{$impl};
+  $usleep = $impls{$impl}->();
+  last if defined $usleep;
  }
 
+ skip_all "Could not find a suitable usleep() implementation among: @impls"
+                                                                 unless 
$usleep;
+
  return usleep => $usleep;
 }
 


Reply via email to