我正在使用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地址。
答案 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;
会跳过它。