I have this in my project:
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;
}
I generally use use strict
to check for errors.
The code works with no strict "refs";
instruction, but fails to run without it, yielding error:
Can't use string ("163277181") as a HASH ref while "strict refs" in use at a.pl line 61, <APT> line 45.
line 61 is: $r->{$key} = $value;
I prefer to fix my code, rather than silence it, but can't get what's wrong/how to fix this.
Also, what's correct way to advance a reference to point to the next object? Although it works I do not feel like $r++
is correct construction in here.
thanks a lot in advance.
You use the
$r
variable both as a hash reference$r->{$key}
, and a number$r++
. References numify to an ID, so you can use them as numbers. However, you cannot use a non-reference scalar as a reference (references are not pointers). To make this clear:You can work around the problems by simply creating a new reference in
$r
when a new block begins. You should also scope your other variables properly: do not use globals likeAPT
, and declare your$key
etc. variables inside the loop.Also,
$key
can never beundef
(split
doesn't returnundef
values), and you should not use prototypes.I guess the following code will do what you want:
More on References vs. Pointers:
You cannot use pointer arithmetic in memory safe languages. Perl is such a memory safe language. The references which you can use are similar to pointers in C. They are typed as well (although dynamically), but are reference counted automatically, so that the referenced data structure is freed once it isn't needed. Proponents of garbage collection and memory safety point to less errors (e.g. double
free
) and increased productivity, although some algorithms may not be expressed as elegantly. Most modern languages are memory safe by default.Even if this were C, and
$r++
would point to a new address, I'd have to ask you: Shouldn't youmalloc
new memory? Memory allocation is implicit in Perl. The$r = {}
gives us a new, empty hash reference. If you use lexical variables (withmy
), deallocation happens automatically as well.