Acme-Sort-Sleep

 view release on metacpan or  search on metacpan

local/lib/perl5/Future/Phrasebook.pod  view on Meta::CPAN


 sub func {
    foreach my $item ( @LIST ) {
       if( COND($item) ) {
          return $item;
       }
    }
    return MAKE_NEW_ITEM();
 }

The C<Future::Utils::call_with_escape> function allows this general form of
control flow, by calling a block of code that is expected to return a future,
and itself returning a future. Under normal circumstances the result of this
future propagates through to the one returned by C<call_with_escape>.

However, the code is also passed in a future value, called here the "escape
future". If the code captures this future and completes it (either by calling
C<done> or C<fail>), then the overall returned future immediately completes
with that result instead, and the future returned by the code block is
cancelled.

 my $f = call_with_escape {
    my $escape_f = shift;

    ( repeat {
       my $item = shift;
       COND($item)->then( sub {
          my ( $result ) = @_;
          if( $result ) {
             $escape_f->done( $item );
          }
          return Future->done;
       })
    } foreach => \@ITEMS )->then( sub {
       MAKE_NEW_ITEM();
    });
 };

Here, if C<$escape_f> is completed by the condition test, the future chain
returned by the code (that is, the C<then> chain of the C<repeat> block
followed by C<MAKE_NEW_ITEM()>) will be cancelled, and C<$f> itself will
receive this result.

=head1 CONCURRENCY

This final section of the phrasebook demonstrates a number of abilities that
are simple to do with C<Future> but can't easily be done with regular
call/return style programming, because they all involve an element of
concurrency. In these examples the comparison with regular call/return code

local/lib/perl5/Future/Utils.pm  view on Meta::CPAN


use Exporter 'import';
# Can't import the one from Exporter as it relies on package inheritance
sub export_to_level
{
   my $pkg = shift; local $Exporter::ExportLevel = 1 + shift; $pkg->import(@_);
}

our @EXPORT_OK = qw(
   call
   call_with_escape

   repeat
   try_repeat try_repeat_until_success
   repeat_until_success

   fmap  fmap_concat
   fmap1 fmap_scalar
   fmap0 fmap_void
);

local/lib/perl5/Future/Utils.pm  view on Meta::CPAN

our @CARP_NOT = qw( Future );

use Future;

=head1 NAME

C<Future::Utils> - utility functions for working with C<Future> objects

=head1 SYNOPSIS

 use Future::Utils qw( call_with_escape );

 my $result_f = call_with_escape {
    my $escape_f = shift;
    my $f = ...
       $escape_f->done( "immediate result" );
       ...
 };

Z<>

 use Future::Utils qw( repeat try_repeat try_repeat_until_success );

 my $eventual_f = repeat {
    my $trial_f = ...
    return $trial_f;

local/lib/perl5/Future/Utils.pm  view on Meta::CPAN

completeness).

=cut

sub call(&)
{
   my ( $code ) = @_;
   return Future->call( $code );
}

=head2 call_with_escape

   $f = call_with_escape { CODE }

I<Since version 0.22.>

The C<call_with_escape> function invokes a block of code that returns a
future, and passes in a separate future (called here an "escape future").
Normally this is equivalent to the simple C<call> function. However, if the
code captures this future and completes it by calling C<done> or C<fail> on
it, the future returned by C<call_with_escape> immediately completes with this
result, and the future returned by the code itself is cancelled.

This can be used to implement short-circuit return from an iterating loop or
complex sequence of code, or immediate fail that bypasses failure handling
logic in the code itself, or several other code patterns.

 $f = $code->( $escape_f )

(This can be considered similar to C<call-with-escape-continuation> as found
in some Scheme implementations).

=cut

sub call_with_escape(&)
{
   my ( $code ) = @_;

   my $escape_f = Future->new;

   return Future->wait_any(
      Future->call( $code, $escape_f ),
      $escape_f,
   );
}

=head1 REPEATING A BLOCK OF CODE

The C<repeat> function provides a way to repeatedly call a block of code that
returns a L<Future> (called here a "trial future") until some ending condition
is satisfied. The C<repeat> function itself returns a C<Future> to represent
running the repeating loop until that end condition (called here the "eventual
future"). The first time the code block is called, it is passed no arguments,

local/lib/perl5/Module/Build/PPMMaker.pm  view on Meta::CPAN

    print "Using default codebase '$distfile'\n";
    @codebase = ($distfile);
  }

  my %dist;
  foreach my $info (qw(name author abstract version)) {
    my $method = "dist_$info";
    $dist{$info} = $build->$method() or die "Can't determine distribution's $info\n";
  }

  $self->_simple_xml_escape($_) foreach $dist{abstract}, @{$dist{author}};

  # TODO: could add <LICENSE HREF=...> tag if we knew what the URLs were for
  # various licenses
  my $ppd = <<"PPD";
<SOFTPKG NAME=\"$dist{name}\" VERSION=\"$dist{version}\">
    <ABSTRACT>$dist{abstract}</ABSTRACT>
@{[ join "\n", map "    <AUTHOR>$_</AUTHOR>", @{$dist{author}} ]}
    <IMPLEMENTATION>
PPD

local/lib/perl5/Module/Build/PPMMaker.pm  view on Meta::CPAN

  # We only include these tags if this module involves XS, on the
  # assumption that pure Perl modules will work on any OS.
  if (keys %{$build->find_xs_files}) {
    my $perl_version = $self->_ppd_version($build->perl_version);
    $ppd .= sprintf(<<'EOF', $self->_varchname($build->config) );
        <ARCHITECTURE NAME="%s" />
EOF
  }

  foreach my $codebase (@codebase) {
    $self->_simple_xml_escape($codebase);
    $ppd .= sprintf(<<'EOF', $codebase);
        <CODEBASE HREF="%s" />
EOF
  }

  $ppd .= <<'EOF';
    </IMPLEMENTATION>
</SOFTPKG>
EOF

local/lib/perl5/Module/Build/PPMMaker.pm  view on Meta::CPAN

  # Append "-5.8" to architecture name for Perl 5.8 and later
  if ($] >= 5.008) {
      my $vstring = sprintf "%vd", $^V;
      $vstring =~ s/\.\d+$//;
      $varchname .= "-$vstring";
  }
  return $varchname;
}

{
  my %escapes = (
		 "\n" => "\\n",
		 '"' => '&quot;',
		 '&' => '&amp;',
		 '>' => '&gt;',
		 '<' => '&lt;',
		);
  my $rx = join '|', keys %escapes;

  sub _simple_xml_escape {
    $_[1] =~ s/($rx)/$escapes{$1}/go;
  }
}

1;
__END__


=head1 NAME

Module::Build::PPMMaker - Perl Package Manager file creation

local/lib/perl5/Module/Build/Platform/VMS.pm  view on Meta::CPAN

  # or if we get a single arg that is an array reference, quote the
  # elements of it and return the reference.
  my ($self, @args) = @_;
  my $got_arrayref = (scalar(@args) == 1
                      && ref $args[0] eq 'ARRAY')
                   ? 1
                   : 0;

  # Do not quote qualifiers that begin with '/'.
  map { if (!/^\//) {
          $_ =~ s/\"/""/g;     # escape C<"> by doubling
          $_ = q(").$_.q(");
        }
  }
    ($got_arrayref ? @{$args[0]}
                   : @args
    );

  return $got_arrayref ? $args[0]
                       : join(' ', @args);
}

local/lib/perl5/Module/Build/Platform/Windows.pm  view on Meta::CPAN

    }
  }

  return join " ", @quoted;
}


sub split_like_shell {
  # As it turns out, Windows command-parsing is very different from
  # Unix command-parsing.  Double-quotes mean different things,
  # backslashes don't necessarily mean escapes, and so on.  So we
  # can't use Text::ParseWords::shellwords() to break a command string
  # into words.  The algorithm below was bashed out by Randy and Ken
  # (mostly Randy), and there are a lot of regression tests, so we
  # should feel free to adjust if desired.

  (my $self, local $_) = @_;

  return @$_ if defined() && ref() eq 'ARRAY';

  my @argv;



( run in 0.430 second using v1.01-cache-2.11-cpan-c21f80fb71c )