Reputation: 18322
I'm doing this:
sub worker {
my ($job, @action) = @$_; #<-- error thrown here
Build($job, @action[0]);
}
for (1..NUM_WORKERS) {
async {
while (defined(my $job = $q->dequeue())) {
worker($job);
}
};
}
$q->enqueue([$_, 'clean']) for @compsCopy;
# When you're done adding to the queue.
$q->end();
$_->join() for threads->list();
When this executes, I get:
Thread 8 terminated abnormally: Can't use string ("8") as an ARRAY ref while "strict refs" in use (@ the line referenced above)
What am I doing wrong here?
edit: To give more insight into what I'm trying to accomplish, I want to be able to do something like:
$q->enqueue([$_, 'clean']) for @compsCopy; #clean
$q->enqueue([$_, 'l1']) for @compsCopy; #build
$q->enqueue([$_, '']) for @compsCopy; #link
Where a user could specify when they're running the script, which $action
s they want to perform on the components (directories).
Upvotes: 2
Views: 99
Reputation: 35208
If the first parameter to worker is an array reference, then you do the following:
sub worker {
my ($job, @action) = @{$_[0]};
$_
and @_
may look similar but they are different variables. Use the array @_
for accessing the parameters passed to that subroutine. $_[0]
will hold the first element of that array.
Note: I'd advise that you come up with a different name for the first captured parameter to the worker
sub. Reusing $job
is confusing. Inside the sub it looks like my ($val, @action) = ...
might be more semantically accurate.
Now, if we undo all the changes the OP made, we get back something that uses a saner parameter order and a doesn't use the name $job
for two different things.
sub worker {
my ($job) = @_;
my ($job_type, @job_params) = @$job;
if ($job_type eq 'clean') {
clean(@job_params);
}
# elsif ($job_type eq '...') {
# ...
# }
# ...
}
for (1..NUM_WORKERS) {
async {
while (defined(my $job = $q->dequeue())) {
worker($job);
}
};
}
$q->enqueue([ clean => $_ ]) for @compsCopy;
# When you're done adding to the queue.
$q->end();
$_->join() for threads->list();
Upvotes: 5