简体   繁体   中英

How to check rows returned by fetchall_arrayref method in Perl?

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

  1. that the top-level reference $r is defined (that the call worked), and

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM