在./parse_rss.pl第27行的字符串eq中使用未初始化的值

时间:2016-03-21 18:30:19

标签: arrays linux perl ubuntu

背景

我不是PERL专家,但致力于将一些脚本迁移到新服务器,使用更新版本的Perl和PHP,所有其他脚本都可以正常工作,但这个特定的脚本不起作用。

我已经安装了此脚本运行所需的所有模块,并且这些与PM相关的错误已经停止。

环境:

  • 运行Web服务器
  • Ubuntu 12.04 LTS 64位
  • Apache 2
  • Mysql
  • PHP5
  • FREETDS
  • 所有防火墙权限和远程数据库连接 经过测试和验证
  • 所有必需的Perl模块和Apache / PHP5 扩展测试和验证

脚本功能:

该脚本旨在从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";
        }
}

非常感谢对此的任何帮助

2 个答案:

答案 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";
    }
}