在子例程中通过引用操作Perl对象

dzo*_*atz 3 perl reference perl-module object subroutine

我有一个Perl程序和包WorkerLog.

Worker几乎完成所有计算,我想通过引用Worker子例程以及一些其他参数(标量和数组)来传递一个对象.我曾见过这样的例子这个这个.

他们通过放入子@_,然后操纵对象来处理这个问题.我也找到了一种通过使用索引来操纵它们的方法,比如@{$_[i]}.问题是,当我尝试这样的代码时,我收到一个错误: Can't call method "write" on unblessed reference at ...

代码片段如下.

主要:

use strict;
use warnings;
use Log;
use Worker;

my $log = Log->new();
my $worker = Worker->new();
my $scalar = "SomeURLhere";
my @array = ('red','blue','white');

# I do some stuff with $log object
#...
# Now I want to pass data to the Worker
$worker->subFromWorker($scalar, \$log, \@array);
Run Code Online (Sandbox Code Playgroud)

工人:

use strict;
use warnings;
package Worker;

sub new {
    my $class = shift;
    my $self = {};
    bless $self, $class;
    return $self;
}

sub subFromWorker{
    my ($self) = shift;
    my $scalar = $_[0];
    #my ($log) = $_[1];
    my @array = @{$_[2]};

    foreach my $item (@array){
        print $item;
    }

    $_[1]->write("The items from url $scalar are printed.");

    #Same thing happens if I use $log here
}
Run Code Online (Sandbox Code Playgroud)

在C#中,这是以不同的方式处理的 - 您可以通过值或引用将参数发送到方法,然后在专门的方法中执行您想要的操作(预编写方法以通过引用或值处理参数).我以为在Perl发送使用时\parameter会发送参考.

Dav*_*oss 6

对象是引用.参考是标量值.

如果要将数组或散列传递给子例程,那么通常需要传递对它们的引用 - 因为Perl参数传递对标量值的效果要好得多.

但是$log已经是对你的对象的引用.因此,您无需参考它.您最终传递了对引用的引用.因此,当您将该参数复制到$log子例程中时,您将获得额外的,不必要的引用级别.

解决方法是将$log标量传递给子例程.

$worker->subFromWorker($scalar, $log, \@array); # $log, not \$log
Run Code Online (Sandbox Code Playgroud)

其他一切都会正常工作.