make weaken work on any ref, not just blessed refs
[p5sagit/curry.git] / lib / curry.pm
index 7f35f6c..9fd6559 100644 (file)
@@ -1,8 +1,14 @@
 package curry;
 
-our $VERSION = '1.0';
+our $VERSION = '1.001000';
 $VERSION = eval $VERSION;
 
+our $curry = sub {
+  my ($invocant, $code) = splice @_, 0, 2;
+  my @args = @_;
+  sub { $invocant->$code(@args => @_) }
+};
+
 sub AUTOLOAD {
   my $invocant = shift;
   my ($method) = our $AUTOLOAD =~ /^curry::(.+)$/;
@@ -16,13 +22,23 @@ package curry::weak;
 
 use Scalar::Util ();
 
+$curry::weak = sub {
+  my ($invocant, $code) = splice @_, 0, 2;
+  Scalar::Util::weaken($invocant) if length ref $invocant;
+  my @args = @_;
+  sub {
+    return unless defined $invocant;
+    $invocant->$code(@args => @_)
+  }
+};
+
 sub AUTOLOAD {
   my $invocant = shift;
-  Scalar::Util::weaken($invocant) if Scalar::Util::blessed($invocant);
+  Scalar::Util::weaken($invocant) if length ref $invocant;
   my ($method) = our $AUTOLOAD =~ /^curry::weak::(.+)$/;
   my @args = @_;
   return sub {
-    return unless $invocant;
+    return unless defined $invocant;
     $invocant->$method(@args => @_);
   }
 }
@@ -59,6 +75,46 @@ is equivalent to:
     };
   };
 
+If you want to pass a weakened copy of an object to a coderef, use the
+C< $weak > package variable:
+
+ use curry::weak;
+
+ my $code = $self->$curry::weak(sub {
+  my ($self, @args) = @_;
+  print "$self must still be alive, because we were called (with @args)\n";
+ }, 'xyz');
+
+which is much the same as:
+
+ my $code = do {
+  my $sub = sub {
+   my ($self, @args) = @_;
+   print "$self must still be alive, because we were called (with @args)\n";
+  };
+  Scalar::Util::weaken(my $weak_obj = $self);
+  sub {
+   return unless $weak_obj; # in case it already went away
+   $sub->($weak_obj, 'xyz', @_);
+  }
+ };
+
+There's an equivalent - but somewhat less useful - C< $curry > package variable:
+
+ use curry;
+
+ my $code = $self->$curry::curry(sub {
+  my ($self, $var) = @_;
+  print "The stashed value from our ->something method call was $var\n";
+ }, $self->something('complicated'));
+
+Both of these methods can also be used if your scalar is a method name, rather
+than a coderef.
+
+ use curry;
+
+ my $code = $self->$curry::curry($methodname, $self->something('complicated'));
+
 =head1 RATIONALE
 
 How many times have you written