在散列上使用键时出错

时间:2014-07-13 17:30:59

标签: perl hash

我有以下代码:

my $xmlrpc = XML::RPC->new('http://api.opensubtitles.org/xml-rpc');
my $result = $xmlrpc->call('SearchSubtitles', $token, @args);    

&lp ("Number of subtitle files found:".keys $result->{data});
my $count=0;
mkdir "./Subs";
foreach my $key ( keys $result->{data} )
{

编译失败并显示错误:

Type of argument to keys on reference must be unblessed hashref or arrayref at /root/subtitlegetter/getsubs.pl line 210.

在包含keys语句的两行上。

$ result看起来像这样:

$result  = {
          'seconds' => '0.014',
          'status' => '200 OK',
          'data' => [
                      {
                        'SubFeatured' => '0',
                        'SubHearingImpaired' => '0',
                        'SubAuthorComment' => undef,
                        'SubDownloadLink' => 'http://dl.opensubtitles.org/en/download/filead/src-api/vrf-cc714a2b91/1951829762.gz',
                        'MovieNameEng' => undef,
                        'SubDownloadsCnt' => '2225',
                        'MovieName' => '"24" Day 4: 7:00 a.m.-8:00 a.m.',
                        'LanguageName' => 'English',
                        'MovieFPS' => '25.000',
                        'SeriesIMDBParent' => '285331',
                        'MovieHash' => '9dfc670867516a39',
                        'SeriesEpisode' => '1',
                        'UserNickName' => 'dvkempen',
                        'MovieYear' => '2005',
                        'SubSize' => '41095',
                        'MovieKind' => 'episode',
                        'IDSubMovieFile' => '125384',
                        'ZipDownloadLink' => 'http://dl.opensubtitles.org/en/download/subad/src-api/vrf-b48cd22d58/3253187',
                        'SubBad' => '0',
                        'ISO639' => 'en',
                        'IDSubtitle' => '3253187',
                        'MovieReleaseName' => '24.S04E01.WS.DVDRip.XviD-MEDiEVAL',
                        'MatchedBy' => 'moviehash',
                        'MovieTimeMS' => '2474000',
                        'UserID' => '1019339',
                        'SubFormat' => 'srt',
                        'MovieByteSize' => '366661632',
                        'SubRating' => '0.0',
                        'SubComments' => '0',
                        'SubActualCD' => '1',
                        'SubHash' => 'ab8ad6d19af1579361929b3f71d61b60',
                        'UserRank' => 'silver member',
                        'IDSubtitleFile' => '1951829762',
                        'SubSumCD' => '1',
                        'SubFileName' => '24.S04E01.WS.DVDRip.XviD-MEDiEVAL.srt',
                        'SubAddDate' => '2008-02-24 20:44:01',
                        'IDMovieImdb' => '502251',
                        'SubtitlesLink' => 'http://www.opensubtitles.org/en/subtitles/3253187/24-day-4-7-00-a-m-8-00-a-m-en',
                        'IDMovie' => '73012',
                        'SeriesSeason' => '4',
                        'SubHD' => '0',
                        'SubLanguageID' => 'eng',
                        'MovieImdbRating' => '8.5'
                      },
                      {
                        'SubFeatured' => '0',
                        'SubHearingImpaired' => '0',
                        'SubAuthorComment' => undef,
                        'SubDownloadLink' => 'http://dl.opensubtitles.org/en/download/filead/src-api/vrf-d165613c14/1951854096.gz',
                        'MovieNameEng' => undef,
                        'SubDownloadsCnt' => '4521',
                        'MovieName' => '"24" Day 4: 7:00 a.m.-8:00 a.m.',
                        'LanguageName' => 'English',
                        'MovieFPS' => '25.000',
                        'SeriesIMDBParent' => '285331',
                        'MovieHash' => '9dfc670867516a39',
                        'SeriesEpisode' => '1',
                        'UserNickName' => 'mephistogrigo',
                        'MovieYear' => '2005',
                        'SubSize' => '40794',
                        'MovieKind' => 'episode',
                        'IDSubMovieFile' => '144086',
                        'ZipDownloadLink' => 'http://dl.opensubtitles.org/en/download/subad/src-api/vrf-18f9de1a19/4380524',
                        'SubBad' => '0',
                        'ISO639' => 'en',
                        'IDSubtitle' => '4380524',
                        'MovieReleaseName' => '24.Season.4.DVDRip.XviD-MEDiEVAL',
                        'MatchedBy' => 'moviehash',
                        'MovieTimeMS' => '2474000',
                        'UserID' => '446711',
                        'SubFormat' => 'srt',
                        'MovieByteSize' => '366661632',
                        'SubRating' => '0.0',
                        'SubComments' => '0',
                        'SubActualCD' => '1',
                        'SubHash' => '4d9d67b580efe4b6378d3cb34b4d2a75',
                        'UserRank' => 'gold member',
                        'IDSubtitleFile' => '1951854096',
                        'SubSumCD' => '1',
                        'SubFileName' => '24.4x01.Day.4.07am-08am.DVDRip.XviD.iNTERNAL-MEDiEVAL.EN.srt',
                        'SubAddDate' => '2008-04-13 14:23:34',
                        'IDMovieImdb' => '502251',
                        'SubtitlesLink' => 'http://www.opensubtitles.org/en/subtitles/4380524/24-day-4-7-00-a-m-8-00-a-m-en',
                        'IDMovie' => '73012',
                        'SeriesSeason' => '4',
                        'SubHD' => '0',
                        'SubLanguageID' => 'eng',
                        'MovieImdbRating' => '8.5'
                      },
                      {
                        'SubFeatured' => '0',
                        'SubHearingImpaired' => '0',
                        'SubAuthorComment' => undef,
                        'SubDownloadLink' => 'http://dl.opensubtitles.org/en/download/filead/src-api/vrf-d383210797/138228.gz',
                        'MovieNameEng' => undef,
                        'SubDownloadsCnt' => '582',
                        'MovieName' => '"24" Day 4: 7:00 a.m.-8:00 a.m.',
                        'LanguageName' => 'English',
                        'MovieFPS' => '25.000',
                        'SeriesIMDBParent' => '285331',
                        'MovieHash' => '9dfc670867516a39',
                        'SeriesEpisode' => '1',
                        'UserNickName' => 'wr975 (a)',
                        'MovieYear' => '2005',
                        'SubSize' => '41175',
                        'MovieKind' => 'episode',
                        'IDSubMovieFile' => '2004768',
                        'ZipDownloadLink' => 'http://dl.opensubtitles.org/en/download/subad/src-api/vrf-b7f71cab8b/4292367',
                        'SubBad' => '0',
                        'ISO639' => 'en',
                        'IDSubtitle' => '4292367',
                        'MovieReleaseName' => '24 - Season 4 - E01-08',
                        'MatchedBy' => 'moviehash',
                        'MovieTimeMS' => '0',
                        'UserID' => '48281',
                        'SubFormat' => 'srt',
                        'MovieByteSize' => '366661632',
                        'SubRating' => '0.0',
                        'SubComments' => '0',
                        'SubActualCD' => '1',
                        'SubHash' => 'b6c8e5422afbb6d748040c5d401445e3',
                        'UserRank' => 'bronze member',
                        'IDSubtitleFile' => '138228',
                        'SubSumCD' => '1',
                        'SubFileName' => '24.401-med.srt',
                        'SubAddDate' => '2005-08-23 00:00:00',
                        'IDMovieImdb' => '502251',
                        'SubtitlesLink' => 'http://www.opensubtitles.org/en/subtitles/4292367/24-day-4-7-00-a-m-8-00-a-m-en',
                        'IDMovie' => '73012',
                        'SeriesSeason' => '4',
                        'SubHD' => '0',
                        'SubLanguageID' => 'eng',
                        'MovieImdbRating' => '8.5'
                      },
                      {
                        'SubFeatured' => '0',
                        'SubHearingImpaired' => '0',
                        'SubAuthorComment' => undef,
                        'SubDownloadLink' => 'http://dl.opensubtitles.org/en/download/filead/src-api/vrf-d596b9fa4f/1952794930.gz',
                        'MovieNameEng' => undef,
                        'SubDownloadsCnt' => '772',
                        'MovieName' => '"24" Day 4: 7:00 a.m.-8:00 a.m.',
                        'LanguageName' => 'English',
                        'MovieFPS' => '25.000',
                        'SeriesIMDBParent' => '285331',
                        'MovieHash' => '9dfc670867516a39',
                        'SeriesEpisode' => '1',
                        'UserNickName' => undef,
                        'MovieYear' => '2005',
                        'SubSize' => '41307',
                        'MovieKind' => 'episode',
                        'IDSubMovieFile' => '2587404',
                        'ZipDownloadLink' => 'http://dl.opensubtitles.org/en/download/subad/src-api/vrf-627cac3bd1/4119493',
                        'SubBad' => '0',
                        'ISO639' => 'en',
                        'IDSubtitle' => '4119493',
                        'MovieReleaseName' => 'S04E01 iNTERNAL WS DVDRip XviD MEDiEVAL',
                        'MatchedBy' => 'moviehash',
                        'MovieTimeMS' => '0',
                        'UserID' => '0',
                        'SubFormat' => 'srt',
                        'MovieByteSize' => '366661632',
                        'SubRating' => '0.0',
                        'SubComments' => '0',
                        'SubActualCD' => '1',
                        'SubHash' => '295dfd2ab8ded0c6d14ed6555796f9d0',
                        'UserRank' => undef,
                        'IDSubtitleFile' => '1952794930',
                        'SubSumCD' => '1',
                        'SubFileName' => '24.S04E01.iNTERNAL.WS.DVDRip.XviD-MEDiEVAL_(ENGLISH)_DJJ.HOME.SAPO.PT.srt',
                        'SubAddDate' => '2011-03-01 22:37:54',
                        'IDMovieImdb' => '502251',
                        'SubtitlesLink' => 'http://www.opensubtitles.org/en/subtitles/4119493/24-day-4-7-00-a-m-8-00-a-m-en',
                        'IDMovie' => '73012',
                        'SeriesSeason' => '4',
                        'SubHD' => '0',
                        'SubLanguageID' => 'eng',
                        'MovieImdbRating' => '8.5'
                      }
                    ]
        };

我发现很难将我的头围绕在键上,来自一种没有哈希的编程语言。能否让我知道代码有什么问题?

我应该提一下,虽然我已经使用了严格和警告,但是在Windows上运行的Activestate perl 5.16.3上编译相同的代码,而在Debian上运行的perl 5.14.2则无法编译。

编辑:我已根据Dumper的数据更新了$ result的内容。

2 个答案:

答案 0 :(得分:6)

keys函数需要一个有效的哈希(或数组,在5.12或更高版本中)作为其参数。在5.14中引入了一个实验性功能,其中几个这样的数组/散列函数(包括keyspush和其他函数)将隐式尝试取消引用标量表达式,这将允许您执行以下操作:

my $hash_ref = { foo => 1 };
print keys $hash_ref;

而不是明确解除引用:

my $hash_ref = { foo => 1 };
print keys %{ $hash_ref };

但是,此功能被认为是高度实验性的*,可能会在将来的版本中删除。对它的有效使用(例如上面的例子)将产生警告:

keys on reference is experimental at ... line ...

无效使用会产生您获得的错误:

my $foo = "This is not a hash ref";
print keys $foo;

Type of argument to keys on reference must be unblessed hashref or arrayref at -e line 1.

*实验具有关于Perl功能的官方意义。标记为实验性的任何功能都很容易被删除和/或向后兼容性更改而无需进一步警告。

解决问题的方法是不在标量表达式上使用keys。这意味着您需要适当地取消引用您的数据结构访问,因此keys的参数是数组或哈希变量。如果我没有误解你编写结构的方式,那么语法就像:

foreach my $key (keys %{ $result->{data} }) { ... }

答案 1 :(得分:1)

我建议你不要在标量或数组上使用keys。 Perl perldoc(强调我的):

  

从Perl 5.14开始,keys可以使用标量EXPR,它必须包含对未经处理的散列或数组的引用。该参数将自动解除引用。 keys的这一方面被认为具有高度的实验性。在未来的Perl版本中,确切的行为可能会发生变化。

   for (keys $hashref) { ... }
   for (keys $obj->get_arrayref) { ... }

相反,只需在哈希上使用它,就像这样:

foreach my $key ( keys %{$result->{data}[0]} ) {