地理IP查找上的Perl未定义错误

时间:2014-09-08 15:47:28

标签: perl error-handling module undefined

我正在使用Geo::IP在ip地址上执行位置查找。一切正常,直到我遇到一个不在geo ip lookup数据库中的ip地址,程序突然关闭,发出此错误

Can't call method "city" on an undefined value at script.pl line 16.

当前代码如下所示

 $gi = Geo::IP->open("/usr/local/share/GeoIP/GeoLiteCity.dat", GEOIP_STANDARD);
 my $record = $gi->record_by_addr($key);
 my $city= $record->city;

关于如何通过此方式的任何建议?它完全正常,直到它到达该模块中未定义的IP地址。

2 个答案:

答案 0 :(得分:3)

查看Geo :: IP源,如果IP地址不在数据库中,则返回undef。因此,要绕过问题,您可以执行以下操作:

my $record = $gi->record_by_addr($key);
## check that $record is defined
if ($record) {
    my $city= $record->city;
    ...
}
else {
    # issue an error message if wanted
    warn "No record found for $key";
}

来自Geo :: IP来源的相关代码:

您使用的功能是record_by_addr。从源record_by_addr开始,get_city_record_as_hash*record_by_addr = \&get_city_record_as_hash; 的别名(有关用于为函数创建“别名”的语法,请参阅perlref):

get_city_record_as_hash

#this function returns the city record as a hash ref sub get_city_record_as_hash { my ( $gi, $host ) = @_; my %gir; @gir{qw/ country_code country_code3 country_name region city postal_code latitude longitude dma_code area_code continent_code region_name metro_code / } = $gi->get_city_record($host); return defined($gir{latitude}) ? bless( \%gir, 'Geo::IP::Record' ) : undef; } 的代码如下:

get_city_record

此代码使用您提供的IP地址$host作为参数运行get_city_record。如果%gir找到记录,则它返回的数据会填充$gir{latitude}哈希值。 sub的最后一行使用[if-else]的[三元形式]来评估获取记录是否成功,并返回适当的结果。它检查是否定义了Geo::IP::Record,如果是,则创建并返回city对象(可以使用undef等方法查询)。如果不是,则返回# is $gir{latitude} defined? if (defined ($gir{latitude})) { # yes: create a Geo::IP::Record object with the data in %gir # return that object return bless( \%gir, 'Geo::IP::Record' ) } else { # no: return undefined. return undef; }

查看最后一行的更简单方法是:

{{1}}

答案 1 :(得分:1)

我建议你在这里需要Data::Dumper,告诉你$record发生了什么。我猜想record_by_addr($key);是您问题的根源,并且由于$key在某种程度上不好,$record未定义。

因此可以修复:

use Data::Dumper;
print Dumper \$record;

我猜测$record将是未定义的,因此:

next unless $record; 

会跳过它。