我正在编写专用的ICS(iCalendar文件)解析器。
我将数组传递给子程序。除$notdates
之外的所有变量都是单个值,这是逗号分隔的日期列表。
@entryl = ($dtstart, $dtend, $attendee, $lastmod, $uid, $notdates);
&entrytoarray(@entryl);
sub entrytoarray {
# print Dumper @_;
my $shiftdur = (&stamptoepoc($_[1]) - &stamptoepoc($_[0])) / 60 / 60;
my $attendee = $_[2];
my $deleted = $_[5];
$attendee =~ /ATTENDEE;USER-KEY=([^;]*);CN=([^;]*);.*:(.*)/;
my %ehash = (
"STARTDATE" , &stamptodate($_[0]),
"ENDDATE" , &stamptodate($_[1]),
"STARTSTAMP" , $_[0],
"ENDSTAMP" , $_[1],
"USERKEY" , $1,
"CN" , $2,
"EMAIL" , $3,
"LASTMOD" , $_[3],
"UID" , $_[4],
"DURATION" , $shiftdur
);
# Only keep current data
my $fdays = 4;
my $tdays = 7;
chomp(my $curstamp = `TZ="UTC" date -d "$fdays days" +"%Y%m%d%H%M00"`);
chomp(my $stpstamp = `TZ="UTC" date -d "$tdays days" +"%Y%m%d%H%M00"`);
if (($_[0] > $curstamp) && ($_[1] < $stpstamp)) {
if (defined($deleted)) {
my @deleted = split /,/, $deleted;
foreach (@deleted) {
if ($_ ne $_[0]) {
push(@entry, \%ehash);
}
}
}
else {
push(@entry, \%ehash);
}
}
print Dumper @entry;
这大部分都符合预期:
$VAR1 = {
'DURATION' => '5',
'STARTSTAMP' => '20141122230000',
'UID' => '20141114T010539Z--1092363482',
'LASTMOD' => '20141118214419',
'STARTDATE' => '2014-11-22 23:00:00',
'EMAIL' => 'xxxxxxxxxxxxx',
'ENDDATE' => '2014-11-23 04:00:00',
'CN' => 'xxxxxxxxxxx',
'ENDSTAMP' => '20141123040000',
'KEY' => 'xxxxxxxxxxxxxxxxxx'
};
$VAR2 = {
'EMAIL' => 'xxxxxxxxxxxxx',
'ENDDATE' => '2014-11-23 23:00:00',
'ENDSTAMP' => '20141123230000',
'KEY' => 'xxxxxxxxxxx',
'CN' => 'xxxxxxxxxxxxxx',
'STARTDATE' => '2014-11-23 19:00:00',
'LASTMOD' => '20141118205901',
'UID' => '20141114T010456Z--1092363482',
'DURATION' => '4',
'STARTSTAMP' => '20141123190000'
};
$VAR3 = $VAR2;
$ VAR3 = $ VAR2来自哪里?
答案 0 :(得分:1)
我猜这部分是罪魁祸首:
foreach (@deleted) {
if ($_ ne $_[0]) {
push(@entry, \%ehash);
}
}
如果数组中有多个值,则if语句可以为真两次,因此将值推两次。除非这是想要的行为,否则我会确保只推送一个值。您可以使用grep
代替:
if (grep { $_ ne $_[0] } @deleted) {
push @entry, \%ehash;
}
请注意,这会取代foreach
循环。
答案 1 :(得分:0)
您的数组@entry
包含哈希引用。 Data::Dumper
表示数组的第一个和第二个元素引用两个不同的哈希值,而第三个元素引用与第二个相同的哈希值。
您没有显示@entry
的来源,但我希望所有三个元素都可以引用%ehash
。
问题在于,如果继续将%ehash
的引用推送到@entry
,它们都指向相同的数据项,并且不会记录哈希的中间状态。 / p>
除非你的意思是entrytoarray
只推送一个的%ehash
副本(在这种情况下会出现一个我们看不到的单独问题),你需要修复它写作
push @entry, { %ehash }
复制哈希并返回对副本的引用,或者您可以在%ehash
循环内声明并填充foreach
,这将在每次创建一个新哈希围绕循环。