Arrays hashrefs问题的Perl数组
我在我的项目中有:Arrays hashrefs问题的Perl数组,arrays,perl,hashref,Arrays,Perl,Hashref,我在我的项目中有: sub get_src_info($) { my $package = shift; my ($key,$value,$tail) =("","",""); my (@APT_INFO,$r); open APT, "apt-cache showsrc $package|"; while (<APT>){ chomp;
sub get_src_info($) {
my $package = shift;
my ($key,$value,$tail) =("","","");
my (@APT_INFO,$r);
open APT, "apt-cache showsrc $package|";
while (<APT>){
chomp;
($key,$value,$tail) = split /:/;
if (defined ($key) && defined ($value)) {
$value =~ s/^\s+|\s+$//;
if (defined($tail)) {
$value = "$value:$tail";
}
if ( $key eq "Package" or $key eq "Version" ) {
$r->{$key} = $value;
}
}
if(/^$/) { push @APT_INFO,$r++; }
}
close APT;
return @APT_INFO;
}
第61行是:$r->{$key}=$value代码>
我更喜欢修复代码,而不是让代码沉默,但不知道哪里出了问题/如何修复
另外,什么是正确的方法来推进一个指向下一个对象的引用?虽然它可以工作,但我觉得这里的$r++
结构不正确
非常感谢。您使用$r
变量既作为哈希引用$r->{$key}
,又作为数字$r++
。将numify引用到ID,因此可以将其用作数字。但是,不能将非引用标量用作引用(引用不是指针)。为了说明这一点:
my $reference = { foo => 1 };
my $numified = 0 + $reference; # is now 163277181
say $numified->{foo}; # does not work under strict "refs"
# ${"163277181"}{foo} is equivalent: This looks for global variable %163277181
只要在新块开始时在$r
中创建一个新引用,就可以解决这些问题。您还应该正确地确定其他变量的范围:不要使用全局变量,如APT
,并在循环中声明$key
等变量
另外,$key
永远不能undef
(split
不会返回undef
值),您不应该使用原型
我想下面的代码可以满足您的要求:
use autodie; # automatic error handling, e.g. for `open`
sub get_src_info {
my ($package) = @_;
my $info = {};
my @apt_info;
open my $fh, "-|", "apt", "showsrc", $package; # circumvent the shell for safety
while (<$fh>) {
chomp;
unless (length) {
push @apt_info, $info;
$info = {}; # put a new reference into $info
next;
}
my ($key, $value) = split /:/, $_, 2; # limit number of fragments to 2
next unless $key eq "Package" or $key eq "Version";
s/^\s+//, s/\s+$// for $value; # this trims at *both* ends
$info->{$key} = $value;
}
return @apt_info;
}
使用autodie;#自动错误处理,例如“打开”`
子获取\u src\u信息{
我的($套餐)=@;
我的$info={};
我的@apt_信息;
打开我的$fh、“-|”、“apt”、“showsrc”、“$package;#为安全起见绕过外壳
而(){
咀嚼;
除非(长度){
推送@apt_info,$info;
$info={};#将新引用放入$info中
下一个
}
my($key,$value)=拆分/:/,$,2;#将片段数限制为2
下一步除非$key eq“包”或$key eq“版本”;
s/^\s+//,s/\s+$//表示$value;#这将在*两端修剪
$info->{$key}=$value;
}
返回@apt_info;
}
更多关于参考与指针的信息:
不能在内存安全语言中使用指针算法。Perl就是这样一种内存安全的语言。您可以使用的引用类似于C中的指针。它们也是类型化的(虽然是动态的),但是引用是自动计数的,因此引用的数据结构在不需要时被释放。垃圾收集和内存安全的支持者指出,错误更少(例如,doublefree
)和生产率更高,尽管有些算法可能无法优雅地表达出来。默认情况下,大多数现代语言都是内存安全的
即使这是C,并且$r++
将指向一个新地址,我也不得不问你:你不应该malloc
新内存吗?内存分配在Perl中是隐式的。$r={}
为我们提供了一个新的空哈希引用。如果使用词法变量(使用my
),也会自动取消分配。在您介绍的代码中,$r
是unde
或整数。然后,当您将$value
分配给$r->{$key}
时,尝试使用$r
作为散列引用。所以,不要这样做。我不知道你所说的“提前引用以显示在下一个对象上”是什么意思。同样,我也不知道你所说的“提前引用以指向下一个对象”是什么意思。在Perl中,增量运算符应该只用于非引用标量。对不起,但我不明白您使用“$r++;”做了什么,因为显然$r是一个hashref,而不是一个简单的int。。。
use autodie; # automatic error handling, e.g. for `open`
sub get_src_info {
my ($package) = @_;
my $info = {};
my @apt_info;
open my $fh, "-|", "apt", "showsrc", $package; # circumvent the shell for safety
while (<$fh>) {
chomp;
unless (length) {
push @apt_info, $info;
$info = {}; # put a new reference into $info
next;
}
my ($key, $value) = split /:/, $_, 2; # limit number of fragments to 2
next unless $key eq "Package" or $key eq "Version";
s/^\s+//, s/\s+$// for $value; # this trims at *both* ends
$info->{$key} = $value;
}
return @apt_info;
}