Perl:返回Object对象的值不触发“if”语句

时间:2011-10-31 19:40:18

标签: perl oop

我正在尝试调试我的程序,如果有任何通知,我想向观察者发送通知。

我有一个方法Notify,它返回观察者想要遵循的文件列表。我的debug例程可以帮助我调试我的程序。

这很有效。我看到第二个debug例程打印出值:

foreach my $watcher ($watch->Watcher) {
    debug qq(Sending out notifcations for ) . $watcher->User, 2;
    my @foo = $watcher->Notify;
    if (@foo) {
        debug qq(Change list to notify on: ) . join (", " => $watcher->Notify), 3;
        $watch->SendEmail($watcher);
    }

}

然而,这失败了:

foreach my $watcher ($watch->Watcher) {
    debug qq(Sending out notifcations for ) . $watcher->User, 2;
    if ($watcher->Notify) {
        debug qq(Change list to notify on: ) . join (", " => $watcher->Notify), 3;
        $watch->SendEmail($watcher);
    }

}

第一个和第二个之间的区别:在第一个中,我将$watcher->Notify返回到数组@foo并在@foo上进行测试。在第二个中,我测试了$watcher->Notify的返回值。

Notify子程序如下所示:

sub Notify {
    my $self   = shift;
    my $change = shift;

    $self->{CHANGE} = [] if not exists $self->{CHANGE};
    if (defined $change) {
        push @{$self->{CHANGE}}, $change;
    }
    return sort @{$self->{CHANGE}};
}

等一下......

好的,当我输入这个问题时,我意识到,当我说if ($watcher->Notify)时,我将返回标量上下文,当我说@foo = $watcher->Notify时,我将返回列表上下文。进一步测试:

foreach my $watcher ($watch->Watcher) {
    debug qq(Sending out notifcations for ) . $watcher->User, 2;
    my $foo = $watcher->Notify;   #Now a SCALAR and not a LIST
    if ($foo) {
        debug qq(Change list to notify on: ) . join (", " => $watcher->Notify), 3;
        $watch->SendEmail($watcher);
    }

}

显示$foo为空。将我的方法改为:

sub Notify {
    my $self   = shift;
    my $change = shift;

    $self->{CHANGE} = [] if not exists $self->{CHANGE};
    if (defined $change) {
        push @{$self->{CHANGE}}, $change;
    }
    if (wantarray) {
       return sort @{$self->{CHANGE}};
    }
    else {
       return scalar @{$self->{CHANGE}};
   }
}

现在有效。 (方法现在检查我是否需要数组,如果不需要,则返回显式标量)。

问题是为什么。

我想如果我将数组返回到标量上下文中,Perl应该自动为我做scalar(并返回数组中的项数)或者至少连接数组中的所有元素$"作为分隔符。 (我假设第一个,但后者也有效)。

例如:

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say switch);
use Data::Dumper;

my @foo = qw(this that the other);

my $bar = @foo;

say "Bar = $bar   \@foo = @foo";

打印出来:

Bar = 4   @foo = this that the other

我哪里出错了? (我的意思是,除了卖掉我所有的Apple股票,当价格一路上涨到每股40美元时)。

2 个答案:

答案 0 :(得分:3)

您没有返回数组。您返回了标量上下文中调用的sort的结果。根据{{​​3}}:

  

在标量上下文中,sort()的行为未定义。

这意味着它可以做任何想做的事情,包括返回undef

答案 1 :(得分:2)

因为您在标量上下文中返回sort的结果:

来自http://perldoc.perl.org/functions/sort.html

  

在列表上下文中,这会对LIST进行排序并返回已排序的列表   值。在标量上下文中,sort()的行为是未定义的。

编辑:如果您不想使用wantarray,可以更改:

return sort @{$self->{CHANGE}};

为:

return @{ [sort @{$self->{CHANGE}}] };