Я пытаюсь отладить свою программу и хочу отправить уведомления наблюдателю, если есть какие-либо уведомления, чтобы получить.
У меня есть метод 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 долларов за акцию).