Fabio Elia Locatelli
Fabio Elia Locatelli

Reputation: 23

Perl @$ syntax meaning

I have adapted a code fragment for getting column names in DBI and it works fine:

$tableColumns = $databaseStatement->{NAME};

print $fileHandle $documentFormatter->{openTableRow};
foreach(@$tableColumns){
  print $fileHandle $documentFormatter->{openTableHeader};
  print $fileHandle $_;
  print $fileHandle $documentFormatter->{closeTableHeader};
}
print $fileHandle $documentFormatter->{closeTableRow};

However, I do not fully understand why in line 3 I need to use @$ when I iterate over the headers returned by statement execution. Also why would the variable $tableColumns be a scalar rather than an array?

Hope you can clarify this because I'm rather confused :(

Thanks in advance, Fabio

Upvotes: 2

Views: 1431

Answers (2)

elcaro
elcaro

Reputation: 2297

Here, $databaseStatement->{NAME} returns an array ref.

$tableColumns = $databaseStatement->{NAME};

If you were to print $tableColumns you'd see something like ARRAY(0x18af700).

So it's storing an array ref, how do you access that array? You dereference it.

for my $entry ( @{ $tableColumns } ) { ... }

The @$tableColumns is just shorthand syntax for dereferencing.


So what's the rationale for all this?

Perl does not allow you to store lists inside an array or as a hash value; you can only store scalar values. This include references, which then allows you to, for example, store references to an array or hash inside another array or hash.

my @simpsons = ('Homer', 'Marge', 'Bart', 'Lisa', 'Maggie');

my %characters = (
    simpsons => \@simpsons, # Create references to existing array
    flanders => ['Ned', 'Maude', 'Rod', 'Tod'], # Anonymous array-ref
);

$simpsons[2] = 'Bort'; # This will affect the entry in the hash

for my $character ( @{ $characters{simpsons} } ) {
    print $character . "\n";
}

Note that I can't use the shorthand @$characters{simpsons} here, but if if I do my $simpsons = $characters{simpsons} I can then iterate over @$simpsons.

Upvotes: 4

James E Keenan
James E Keenan

Reputation: 311

You state that you have "adapted a code fragment for getting column names in DBI", but it is not immediately evident how you have gotten to that point from the DBI library.

Reading perldoc DBI, the closest I get to something to retrieve column names is:

"column_info"
  $sth = $dbh->column_info( $catalog, $schema, $table, $column );

  # then $sth->fetchall_arrayref or $sth->fetchall_hashref etc

The $sth->fetchall_arrayref would return an array reference. An array reference in Perl 5 is a scalar and is denoted with the '$' sigil. To iterate over the elements of that arrayref, you need to de-reference the arrayref. You can do that with either:

foreach (@$tableColumns) { ...

or, more formally:

foreach (@{$tableColumns}) { ...

Upvotes: 1

Related Questions