I am trying to understand following piece of code, in particular what's happening in line 4, 5 and 6.
I have understood most of it , but just can't seem to understand what's being done with @$r != 1;
in line 4 (does @$r
represents the number of rows returned?) and similarly what's happening with @$r[0]
in line 5 and @$rr[0]
in line 6:
1 my $sth = $dbh->prepare(" a select statement ");
2 $sth->execute();
3 my $r = $sth->fetchall_arrayref();
4 die "Failed to select " if !defined($r) || @$r != 1;
5 my $rr = @$r[0];
6 my $rec = @$rr[0];
7 print "Rec is $rec\n";
Evaluating an array (reference) in scalar context returns the number of elements in the array. The answer to your other questions is that it's just standard dereferencing using ugly syntax and useless intermediate variables.
I believe in teaching people how to fish, though, so consider this code, which is essentially what you're working with:
use strict;
use warnings;
use Data::Dumper;
my $r = [[1, 2, 3]];
my $rr = @$r[0];
my $rec = @$rr[0];
print Dumper($r, $rr, $rec);
Output:
$VAR1 = [
[
1,
2,
3
]
];
$VAR2 = $VAR1->[0];
$VAR3 = 1;
It should be easy to see what's going on now that you can see what each variable holds, right?
The fetchall_arrayref() returns a reference to an array of all rows, in which each element is also a reference to an array, with that row's elements.
Then the die
line checks
that the top-level reference $r
is defined (that the call worked), and
that the size of that array, @$r
, is exactly 1
– so, that the array contains exactly one element. This betrays the expectation that the query will return one row and since the code is prepared to die
for this it may well ask for one row, by fetchrow_arrayref or fetchrow_array .
The @$r
dereferences the $r
arrayref, and in the scalar context imposed by !=
we indeed get the number of elements in the list.
The line 5 is very misleading, to say the least, even as the syntax happens to be legitimate: it extracts the first element and feeds it into a scalar, but using @$r[0]
syntax which would normally imply that we are getting a list, by its sigil @
. It's equivalent to @{$r}[0]
and is an abuse of notation.
It should either clearly get the first element, if that's the intent
my $rr = $r->[0];
or also dereference it to get the whole array
my @row = @{ $r->[0] };
if that's wanted.
The last line that you query does the exact same, using the retrieved $rr
reference. But the first element of the first arrayref (row) is easily obtained directly
my $rec = $r->[0]->[0]; # or $r->[0][0]
what replaces lines 5 and 6.
See perlreftut and perldsc .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.