我正在使用 Geo::IP
对 IP 地址执行位置查找。一切正常,直到我遇到一个不在地理 IP 查找数据库中的 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 地址。
最佳答案
查看 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
的别名(见 perlref 用于为函数创建“别名”的语法):*record_by_addr = \&get_city_record_as_hash;
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
使用 $host
,您提供的 IP 地址,作为参数。如果 get_city_record
找到一条记录,它返回的数据填充 %gir
哈希。 sub的最后一行使用[三元形式的if-else]来判断获取记录是否成功,并返回相应的结果。它检查是否 $gir{latitude}
已定义,如果已定义,则创建并返回 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;
}
关于地理 IP 查找上的 Perl 未定义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25728126/