maybe::start
[scpubgit/Object-Remote.git] / lib / Object / Remote / Future.pm
index 11850d6..3392f68 100644 (file)
@@ -33,10 +33,7 @@ package start;
 
 sub AUTOLOAD {
   my $invocant = shift;
-  my ($method) = our $AUTOLOAD =~ /([^:]+)$/;
-  if (ref($invocant) eq 'ARRAY') {
-    return [ map $_->${\"start::${method}"}, @$invocant ];
-  }
+  my ($method) = our $AUTOLOAD =~ /^start::(.+)$/;
   my $res;
   unless (eval { $res = $invocant->$method(@_); 1 }) {
     my $f = CPS::Future->new;
@@ -51,4 +48,42 @@ sub AUTOLOAD {
   return $res;
 }
 
+package maybe::start;
+
+sub AUTOLOAD {
+  my $invocant = shift;
+  my ($method) = our $AUTOLOAD =~ /^maybe::start::(.+)$/;
+  $method = "start::${method}" if ((caller(1)||'') eq 'start');
+  $invocant->$method(@_);
+}
+
+package then;
+
+sub AUTOLOAD {
+  my $invocant = shift;
+  my ($method) = our $AUTOLOAD =~ /^then::(.+)$/;
+  my @args = @_;
+  # Need two copies since if we're called on an already complete future
+  # $f will be freed immediately
+  my $ret = my $f = CPS::Future->new;
+  $invocant->on_fail(sub { $f->fail(@_); undef($f); });
+  $invocant->on_done(sub {
+    my ($obj) = @_;
+    my $next = $obj->${\"start::${method}"}(@args);
+    $next->on_done(sub { $f->done(@_); undef($f); });
+    $next->on_fail(sub { $f->fail(@_); undef($f); });
+  });
+  return $ret;
+}
+
 1;
+
+=head1 NAME
+
+Object::Remote::Future - Asynchronous calling for L<Object::Remote>
+
+=head1 LAME
+
+Shipping prioritised over writing this part up. Blame mst.
+
+=cut