我正在尝试将过时的perl插件更新为Google的新API(他们更改了搜索调用)。我是Perl的新手,所以我不确定如何正确更新代码。我很确定我在尝试读取哈希时应该是一个数组吗?
数据结构转储:
$VAR1 = {
'station_hits' => bless( do{\(my $o = 1726698624)}, 'Inline::Python::Object' ),
'album_hits' => bless( do{\(my $o = 1726698288)}, 'Inline::Python::Object' ),
'artist_hits' => bless( do{\(my $o = 1726698336)}, 'Inline::Python::Object' ),
'situation_hits' => bless( do{\(my $o = 1726698384)}, 'Inline::Python::Object' ),
'song_hits' => bless( do{\(my $o = 1726698432)}, 'Inline::Python::Object' ),
'playlist_hits' => bless( do{\(my $o = 1726698480)}, 'Inline::Python::Object' ),
'video_hits' => bless( do{\(my $o = 1726698528)}, 'Inline::Python::Object' )
};
代码块:
# Search All Access
sub search {
my $query = shift;
return unless $prefs->get('all_access_enabled');
my $uri = 'googlemusic:search:' . $query;
if (my $result = $cache->get($uri)) {
return $result;
}
my $googleResult;
my $result = {
tracks => [],
albums => [],
artists => [],
};
eval {
$googleResult = $googleapi->search($query, $prefs->get('max_search_items'));
};
if ($@) {
$log->error("Not able to search All Access for \"$query\": $@");
return;
}
#My Attempt
for my $hit (%@{$googleResult->{song_hits}}) {
push @{$result->{tracks}}, to_slim_track($hit->{track});
}
#How it was originally
for my $hit (@{$googleResult->{album_hits}}) {
push @{$result->{albums}}, album_to_slim_album($hit->{album});
}
我只在更改名称后收到此错误:
不是[LINE#]
的ARRAY参考将 search_all_access 更改为搜索
有问题的一行:
for my $hit (@{$googleResult->{song_hits}}) {
我尝试过研究,在前面添加了一个%,但现在我在下一行收到错误。
'newlist'对象在[LINE#+ 1]
中没有属性'track' push @{$result->{tracks}}, to_slim_track($hit->{track});
编辑: 在解释了如何引用哈希应该如何工作之后进行更改后,我得到了这个:
[16-05-23 10:22:36.7283] Slim::Networking::IO::Select::__ANON__ (131) Error: Select task failed calling Slim::Web::HTTP::processHTTP: Can't locate object method "FIRSTKEY" via package "Inline::Python::Object::Data" at /usr/lib/arm-linux-gnueabihf/perl/5.20/Data/Dumper.pm line 224.
; fh=Slim::Web::HTTP::ClientConn=GLOB(0x1007a188)
我不确定他们的代码中是否存在错误,或者Google是否在此最新错误后以不同的结构返回API数据。
答案 0 :(得分:2)
这些对象似乎被抽象掉了。您可以阅读Inline::Python文档,但其中没有任何内容。然而,在code for the Inline::Python::Object中,有一个提示。
两行下来,有这个(省略矿井)。
use overload '%{}' => \&__data__, # [...]
如果它与哈希取消引用一起使用an overload,我们可以肯定它会在这种情况下返回哈希引用。
现在我们需要做的就是修复你引入的语法错误。你做了%@{}
,这是无效的语法。您需要@{}
。
%{}
for my $hit (%{ $googleResult->{song_hits} }) {
push @{$result->{tracks}}, to_slim_track($hit->{track});
}
但是因为Perl中的哈希本质上是列表,所以现在将迭代键和值。这几乎不是一个好主意。相反,你应该iterate over the keys
,然后使用它。或者更有可能的是,您感兴趣的每一个中只有一个密钥。如果有API描述,我建议您检查一下。这可能会有所帮助。
如果没有,Dumper
就像这样。
print Dumper \%{ $googleResult->{song_hits} };
首先取消引用它,确保调用重载。由于Data :: Dumper并不将列表理解为数据结构,因此您将向其传递对返回的哈希的引用,因此您将获得$VAR1={}
而不是$VAR1='foo'; $VAR2='bar'
,依此类推。
答案 1 :(得分:1)
如果您使用Data :: Dumper打印出这些数据结构,您很快就会看到它们的形式。然后您就不必猜测了。另外,不要将面向对象的调用样式误认为是散列访问。 ,它们是相同的,因为这就是Perl5对象的制作方式。
use data::dumper;
print "variable is :" + Dumper(@variable)
答案 2 :(得分:1)
我看不到预期的“更新”是什么,需要改变什么。但这里有一些评论。
首先:语法无效 - 不能有%@{...}
。您可以取消引用对哈希,%{$hashref}
或数组@{$arrayref}
(或标量,$$scalarref
)的引用。
您的数据结构很有趣。首先,它是一个哈希引用。 (或者,更确切地说,匿名哈希。)您可以完全取消引用它以创建哈希,或者可以为特定键提取值
my $href = { 'k1' => 'val1', 'k2' => 'val2' };
my $value_of_k1_key = $href->{'k1'}; # will be == val1
接下来,代码中的'value'正式成为一个对象。 bless
函数将对数据结构(通常是hashref)的引用与类相关联,使其成为该类的对象(它返回)。
所以你真的有
$href = { 'station_hits' => $object, ... }
查询(任何)键后,您将返回该对象。
$object = $googleResult->{song_hits}
根据“#How the original ”下面显示的代码(我假设它有效),对象的数据结构是对数组的引用,而不是哈希,因为它取消引用数组。没关系。奇怪的是,它直接取消引用它,寻找其数据/属性。在一些其他语言的术语中,它正在访问(大概)私人成员。在Perl中,这是合法的并且将检索一个值但通常被认为是坏的,就像它被禁止一样。