背景
我不是PERL专家,但致力于将一些脚本迁移到新服务器,使用更新版本的Perl和PHP,所有其他脚本都可以正常工作,但这个特定的脚本不起作用。
我已经安装了此脚本运行所需的所有模块,并且这些与PM相关的错误已经停止。
环境:
脚本功能:
该脚本旨在从RSS源中提取故事并将其放入远程数据库。
问题:
在旧服务器上,脚本在此新服务器上运行时没有任何问题,我收到以下错误:
在./parse_rss.pl第27行的字符串eq中使用未初始化的值。
第27行如下:
if (ref($item->{'company:symbol'} eq 'ARRAY')) {
next;
请查看以下完整的脚本:
#!/usr/bin/perl
#
use warnings;
use strict;
use DateTime;
use DateTime::Format::ISO8601;
use XML::FeedPP;
my $starttime;
if ($#ARGV == -1) {
$starttime = DateTime::Format::ISO8601->parse_datetime("1970-01-01T00:00:00");
}
else {
$starttime = DateTime::Format::ISO8601->parse_datetime($ARGV[0]);
}
my $feed = XML::FeedPP->new("http://RSS.FEED.URL");
my $num_items = $feed->get_item();
for (my $i = $num_items - 1; $i >= 0; $i--)
{
my $item = $feed->get_item($i);
my $dt = DateTime::Format::ISO8601->parse_datetime($item->pubDate);
if ($dt < $starttime) {
last;
}
if (ref($item->{'company:symbol'} eq 'ARRAY')) {
next;
}
if ($item->title =~ /(.+?) (upgraded|downgraded) to (.+?) from (.+?) at (.+)/) {
print sprintf("%04d-%02d-%02d %02d:%02d:%02d", $dt->year(), $dt->month(), $dt->day(), $dt->hour(), $dt->minute(), $dt->second()) . "|$1|" . $item->{'company:symbol'} . "|$2|$3|$4|$5\n";
}
elsif ($item->title =~ /(.+?) (initiated) with (\w+) (.+?) at (.+)/) {
print sprintf("%04d-%02d-%02d %02d:%02d:%02d", $dt->year(), $dt->month(), $dt->day(), $dt->hour(), $dt->minute(), $dt->second()) . "|$1|" . $item->{'company:symbol'} . "|$2|$4|...None...|$5\n";
}
}
非常感谢对此的任何帮助
答案 0 :(得分:0)
你的括号在错误的地方
if (ref($item->{'company:symbol'} eq 'ARRAY')) {
应该是
if (ref($item->{'company:symbol'}) eq 'ARRAY') {
ref
返回一个字符串,在数组的情况下恰好是ARRAY
。因此,这将检查该哈希元素中的引用是否是数组引用。
答案 1 :(得分:0)
作为TLP says,问题在于您的行
if (ref($item->{'company:symbol'} eq 'ARRAY'))
表达式$item->{'company:symbol'} eq 'ARRAY'
的计算结果为 true 或 false -1或空字符串 - ref
运算符返回false - 空string-in两种情况都是因为它们都不是引用
您打算检查哈希元素是否是数组引用,所以
if (ref $item->{'company:symbol'} eq 'ARRAY')
没有括号可以没问题
您的代码还存在许多其他问题。特别是我认为在循环开始时提取迭代值的函数更为简洁。
所以,例如
if (ref($item->{'company:symbol'} eq 'ARRAY')) {
next;
}
更清楚地写成
my $company_symbol = $item->{'company:symbol'};
next if ref $company_symbol eq 'ARRAY';
以下是您可能更喜欢的代码版本
#!/usr/bin/perl
use warnings;
use strict;
use DateTime;
use DateTime::Format::ISO8601;
use XML::FeedPP;
my $starttime;
if ( @ARGV ) {
$starttime = DateTime::Format::ISO8601->parse_datetime( $ARGV[0] );
}
else {
$starttime = DateTime::Format::ISO8601->parse_datetime('1970-01-01T00:00:00');
}
my $feed = XML::FeedPP->new('http://rss.feed.url');
my $num_items = $feed->get_item;
for ( my $i = $num_items - 1; $i >= 0; --$i ) {
my $item = $feed->get_item($i);
my $company_symbol = $item->{'company:symbol'};
my $pub_date = DateTime::Format::ISO8601->parse_datetime( $item->pubDate );
my $title = $item->title;
last if $pub_date < $starttime;
next if ref $company_symbol eq 'ARRAY';
if ( $title =~ /(.+?) (upgraded|downgraded) to (.+?) from (.+?) at (.+)/ ) {
print join('|',
$pub_date->strftime('%Y-%m-%d %h:%m:%s'),
$1,
$company_symbol,
$2,
$3,
$4,
$5
), "\n";
}
elsif ( $title =~ /(.+?) (initiated) with (\w+) (.+?) at (.+)/ ) {
print join('|',
$pub_date->strftime('%Y-%m-%d %h:%m:%s'),
$1,
$company_symbol,
$2,
$4,
'...None...',
$5
), "\n";
}
}