Domanda

mi è stato scaricato alcune operazioni di manutenzione su un paio di script Perl. Uno dei requisiti è quello di scaricare un paio di dozzine di file (HTTP) in parallelo. Sono andato alla ricerca su CPAN per la soluzione più semplice ed ho trovato questo modulo chiamato IO :: Lambda: :. HTTP

Purtroppo, non ho alcuna esperienza con la programmazione funzionale (e principianti-livello di esperienza Perl), così mentre vedo che tutti gli esempi funzionano come documentato, non posso davvero modificare qualsiasi di loro per soddisfare le mie esigenze.

Ad esempio, l'esempio che viene fornito con il modulo:

#!/usr/bin/perl
# $Id: parallel.pl,v 1.7 2008/05/06 20:41:33 dk Exp $
# 
# This example fetches two pages in parallel, one with http/1.0 another with
# http/1.1 . The idea is to demonstrate three different ways of doing so, by
# using object API, and explicit and implicit loop unrolling
#

use lib qw(./lib);
use HTTP::Request;
use IO::Lambda qw(:lambda);
use IO::Lambda::HTTP qw(http_request);
use LWP::ConnCache;

my $a = HTTP::Request-> new(
  GET => "http://www.perl.com/",
);
$a-> protocol('HTTP/1.1');
$a-> headers-> header( Host => $a-> uri-> host);

my @chain = ( 
  $a, 
  HTTP::Request-> new(GET => "http://www.perl.com/"),
);

sub report
{
  my ( $result) = @_;
  if ( ref($result) and ref($result) eq 'HTTP::Response') {
    print "good:", length($result-> content), "\n";
  } else {
    print "bad:$result\n";
  }
#   print $result-> content;
}

my $style;
#$style = 'object';
#$style = 'explicit';
$style = 'implicit';

# $IO::Lambda::DEBUG++; # uncomment this to see that it indeed goes parallel

if ( $style eq 'object') {
  ## object API, all references and bindings are explicit
  sub handle {
    shift;
    report(@_);
  }
  my $master = IO::Lambda-> new;
  for ( @chain) {
    my $lambda = IO::Lambda::HTTP-> new( $_ );
    $master-> watch_lambda( $lambda, \&handle);
  }
  run IO::Lambda;
} elsif ( $style eq 'explicit') {
  #
  # Functional API, based on context() calls. context is
  # $obj and whatever arguments the current call needs, a RPN of sorts.
  # The context though is not stack in this analogy, because it stays
  # as is in the callback
  #
  # Explicit loop unrolling - we know that we have exactly 2 steps
  # It's not practical in this case, but it is when a (network) protocol
  # relies on precise series of reads and writes
  this lambda {
    context $chain[0];
    http_request \&report;
    context $chain[1];
    http_request \&report;
  };
  this-> wait;
} else {
  # implicit loop - we don't know how many states we need
  # 
  # also, use 'tail'
  this lambda {
    context map { IO::Lambda::HTTP-> new( $_, async_dns => 1 ) } @chain;
    tails { report $_ for @_ };
  };
  this-> wait;
}

funziona come pubblicizzato, ma non posso per la vita di me a capire come modificare sia l' 'oggetto' o esempi 'impliciti' essere limitato ai casi in parallelo N come la seguente dalla sinossi di IO :: Lambda:

# http://search.cpan.org/~karasik/IO-Lambda/lib/IO/Lambda.pm
# crawl for all urls in parallel, but keep 10 parallel connections max
print par(10)-> wait(map { http($_) } @hosts);

Qualcuno mi mostra un esempio di ciò che il codice lambda sarebbe simile dato il vincolo di cui sopra (per esempio limite alle istanze N)?

Inoltre, qual è il modo migliore per iniziare ad imparare la programmazione funzionale? Sembra del tutto estraneo a me.

È stato utile?

Soluzione

Ci sono buone altre opzioni rispetto IO :: Lambda per questo compito, per esempio AnyEvent: : HTTP . Vedere questa precedente domanda SO .

Anche se ho familiarità con la programmazione funzionale, quanto sopra IO :: Lambda sguardi codice di esempio piuttosto difficile da capire per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top