Проходные массивы в Perl - PullRequest
2 голосов
/ 29 июня 2011

Хорошо, я попытаюсь объяснить, что я сделал до сих пор. Я использую Parellel :: ForkManager для получения данных из массива URL-адресов, который затем сохраняется в переменных (value1, value2, value3).

Затем я собираю данные всех этих процессов и отображаю их с помощью $pm->run_on_finish.

#...
my $pm = new Parallel::ForkManager(10);

$pm->run_on_finish (
    sub {
        my @info = @{$data_structure_reference};

        print $info[0];
        print $info[1];
        print $info[2];
    }
);

for my $var (@urls) {

    $pm->start and next;
    #...
    @returned = &something($var);
    #...
    $pm->finish(0, \@returned);

}

sub something {

    #... getting data from each URL and storing it in variables

    my @array = (
        $value1,
        $value2,
        $value3
    );
    return @array;
}

Теперь, что я хочу сделать, так это передать массив, также @value4, и затем отображать эти данные, только если что-то есть в массиве. Итак, я хочу, чтобы это выглядело так:

sub something {

    #... getting data from each URL and storing it in variables

    my @array = (
        $value1,
        $value2,
        $value3,
        @value4
    );
    return @array;
}

А потом я хочу, чтобы он распечатал этот массив, только если в нем что-то есть.

К сожалению, я не совсем уверен, как это сделать.

Ответы [ 3 ]

2 голосов
/ 29 июня 2011

Я предполагаю, что вы спрашиваете, как вернуть массив вместе с тремя скалярами, возвращенными из подпункта something(), и распечатать его?

Я также предполагаю, что эти три скаляра - то, что упоминаетсякак в @info.

Мне кажется, что самый простой способ - просто прикрепить их к концу возвращаемого массива, использовать три первых значения, и, если что-то осталось, вывести это тоже.

$pm->run_on_finish (
    sub {
        my @info = @{$data_structure_reference};

        print splice @info, 0, 3;
        print @info if (@info);
    }
);

sub something {
    return (
            $value1,
            $value2,
            $value3,
            @value4
        );
}

Как вы заметите, вам не нужно заполнять фиктивный массив для возвращаемого значения, просто возвращайте значения в скобках.Вам не нужно разыменовывать массив, так как вы можете использовать массив @info прямо вверх, если склеиваете первые три значения.

Мне нравится это просто.Если это работает.

2 голосов
/ 30 июня 2011

Ранее я предоставил простое решение этой проблемы.Он может использовать потоки (use threads;) или процессы (use forks;).

use threads;  # or: use forks;
use Thread::Queue qw( );

use constant NUM_WORKERS => 10;

my $request_q  = Thread::Queue->new();
my $response_q = Thread::Queue->new();

# Create the workers.
for (1..NUM_WORKERS) {
   (async {
      while (defined(my $request = $request_q->dequeue())) {
         $response_q->enqueue(process_request($request));
      }
   })->detach();
}

# Submit work to workers.
$request_q->enqueue(@requests);

# Signal the workers they are done.
$request_q->enqueue(undef) for 1..NUM_WORKERS;

# Collect the results.
my $working = NUM_WORKERS;
while ($working) {
   my $result = $response_q->dequeue();
   if (!defined($result)) {
       --$working;
       next;
   }
   process_response($result);
}

Работа, выполняемая в дочерних элементах, выполняется process_request.

sub process_request {
    # ...

    return [
        $value1,
        $value2,
        $value3,
        \@value4,
    ];
}

.Результаты передаются в process_response в родительском элементе.

sub process_response {
    my ($value1, $value2, $value3, $value4) = @{ $_[0] };
    ...
}
1 голос
/ 29 июня 2011

Я не совсем уверен, что вы спрашиваете, но чтобы передать несколько массивов в функцию в Perl, нужно передать по ссылке.

my @array1 = (1, 2, 3);
my @array2 = ('a', 'b', 'c');

&fn(\@array1, \@array2);

Чтобы распечатать массив только в случаекогда оно имеет значение, нужно просто проверить, что оно имеет значение, и напечатать его:

print "@array" if @array;

Хотя хорошая функция "@array" заключается в том, что если @array не имеет значения, тогда "@array" оценивается"".Это позволяет сократить предыдущее утверждение до простого:

print "@array"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...