如何deref @ $ _?

时间:2014-04-03 18:52:03

标签: perl parameters

我这样做:

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();

执行此操作时,我得到:

  

线程8异常终止:使用“严格引用”时,不能使用字符串(“8”)作为ARRAY引用(@上面引用的行)

我在这里做错了什么?

编辑:为了更深入地了解我想要实现的目标,我希望能够做到这样的事情:

$q->enqueue([$_, 'clean']) for @compsCopy; #clean
$q->enqueue([$_, 'l1']) for @compsCopy; #build
$q->enqueue([$_, '']) for @compsCopy; #link

用户可以指定何时运行脚本,哪些$action他们想要对组件(目录)执行。

1 个答案:

答案 0 :(得分:5)

如果worker的第一个参数是数组引用,则执行以下操作:

sub worker {
    my ($job, @action) = @{$_[0]}; 

$_@_可能看起来很相似,但它们是不同的变量。使用数组@_来访问传递给该子例程的参数。 $_[0]将保存该数组的第一个元素。

注意:我建议你为worker子的第一个捕获参数提出一个不同的名称。重用$job令人困惑。在子内部看起来my ($val, @action) = ...可能在语义上更准确。


现在,如果我们撤消OP所做的所有更改,我们会返回使用saner参数顺序的内容,而不会使用名称$job来执行两项不同的操作。

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();