Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

unfamiliar array reference
I'm reading the book Programming the Perl DBI to start work with
databases.  The DBI portion I'm getting OK, but I find the reference
here to @$ confusing. (This code is based from the book.)

my $sth1 = $dbh->prepare("select 'SCM_ORDERS_OUT', message_index,
message_no, message_event, time_stamp, data from log");

$sth1->execute();

my @stash;

while ($array_ref = $sth1->fetchrow_arrayref) {
push @stash, [ @$array_ref ];  ##copy array contents
}

###dump stash contents
foreach $array_ref ( @stash ) {
print "Row: @$array_ref\n";
}

The rows print out fine, so it "works", but I don't understand how.  I
need to be able to work with specific items in the output, such as the
column "data".  How would I reference it, using this example?


Peter Link


Report this thread to moderator Post Follow-up to this message
Old Post
petelink1@yahoo.com
08-19-07 03:02 AM


Re: unfamiliar array reference
On 8/17/07, petelink1@yahoo.com <petelink1@yahoo.com> wrote:
> I'm reading the book Programming the Perl DBI to start work with
> databases.  The DBI portion I'm getting OK, but I find the reference
> here to @$ confusing. (This code is based from the book.)
snip

It is funny that you use the word reference, because $array_ref is a
reference to an array (hence its name).  There are several ways to
access the array referenced by $array_ref.  If you want a specific
element you can say $array_ref->[0] if you want access to the whole
array you can say @$array_ref.  You can read more about reverences in
perldoc perlreftut (also available as
http://perldoc.perl.org/perlreftut.html).

Report this thread to moderator Post Follow-up to this message
Old Post
Chas Owens
08-19-07 03:02 AM


Re: unfamiliar array reference
petelink1@yahoo.com wrote:
> I'm reading the book Programming the Perl DBI to start work with
> databases.  The DBI portion I'm getting OK, but I find the reference
> here to @$ confusing. (This code is based from the book.)
>
> my $sth1 = $dbh->prepare("select 'SCM_ORDERS_OUT', message_index,
> message_no, message_event, time_stamp, data from log");
>
> $sth1->execute();
>
> my @stash;
>
> while ($array_ref = $sth1->fetchrow_arrayref) {
>   push @stash, [ @$array_ref ];  ##copy array contents
> }
>
> ###dump stash contents
> foreach $array_ref ( @stash ) {
>    print "Row: @$array_ref\n";
> }
>
> The rows print out fine, so it "works", but I don't understand how.

@stash is an "Array of Arrays", so to start with I think you should
study "perldoc perllol".

> I need to be able to work with specific items in the output, such as
> the column "data".  How would I reference it, using this example?

foreach my $row ( @stash) {
print "Data: $row->[5]\n";
}

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

Report this thread to moderator Post Follow-up to this message
Old Post
Gunnar Hjalmarsson
08-19-07 03:02 AM


Re: unfamiliar array reference
petelink1@yahoo.com wrote:
> I'm reading the book Programming the Perl DBI to start work with
> databases.  The DBI portion I'm getting OK, but I find the reference
> here to @$ confusing. (This code is based from the book.)
>
> my $sth1 = $dbh->prepare("select 'SCM_ORDERS_OUT', message_index,
> message_no, message_event, time_stamp, data from log");
>
> $sth1->execute();
>
> my @stash;
>
> while ($array_ref = $sth1->fetchrow_arrayref) {
>   push @stash, [ @$array_ref ];  ##copy array contents
> }
>
> ###dump stash contents
> foreach $array_ref ( @stash ) {
>    print "Row: @$array_ref\n";
> }
>
> The rows print out fine, so it "works", but I don't understand how.  I
> need to be able to work with specific items in the output, such as the
> column "data".  How would I reference it, using this example?

The term '@$' is a de-reference of a reference.

To be exact, $array_ref holds a reference to an array.  To access the array 
you need to de-reference it.  There are two ways to doing it.  The following
 are equivalent.

@$array_ref
@{ $array_ref }

You can use these anywhere you use an array:

push @$array_ref, $some_data;
if( grep { /$pattern/ } @{ $array_ref } ){
..
}


--
Just my 0.00000002 million dollars worth,
Shawn

"For the things we have to learn before we can do them, we learn by doing th
em."
Aristotle

Report this thread to moderator Post Follow-up to this message
Old Post
Mr. Shawn H. Corey
08-19-07 03:02 AM


Re: unfamiliar array reference
On Aug 17, 5:07 pm, peteli...@yahoo.com wrote:
> I'm reading the book Programming the Perl DBI to start work with
> databases.  The DBI portion I'm getting OK, but I find the reference
> here to @$ confusing. (This code is based from the book.)
>
> my $sth1 = $dbh->prepare("select 'SCM_ORDERS_OUT', message_index,
> message_no, message_event, time_stamp, data from log");
>
> $sth1->execute();
>
> my @stash;
>
> while ($array_ref = $sth1->fetchrow_arrayref) {
>   push @stash, [ @$array_ref ];  ##copy array contents

Is that seriously from the book?  UGH.  Just declare $array_ref in the
proper scope, and there's no need to take a reference to a dereference
of the reference.

while (my $array_ref  = $sth1->fetchrow_arrayref) {
push @stash, $array_ref;
}

>
> }
>
> ###dump stash contents
> foreach $array_ref ( @stash ) {
>    print "Row: @$array_ref\n";
>
> }
>
> The rows print out fine, so it "works", but I don't understand how.  I
> need to be able to work with specific items in the output, such as the
> column "data".  How would I reference it, using this example?

In this specific example, "data" is the sixth column in the SELECT
query.  You would therefore access it by $array_ref->[5].

I would generally recommend you use the fetchrrow_hashref method
rather than fetchrow_arrayref, so that you can refer to the column by
name.  This will prevent bugs in your code if you later change the
query to add or remove columns.  With fetchrow_hashref, the return
value is a reference to a hash rather than to an array:

while (my $hash_ref = $sth1->fetchrow_hashref()) {
print $hash_ref->{data} . "\n";
}

I agree with other posters - you should read:
perldoc perlref
perldoc perlreftut
perldoc perllol
perldoc perldsc

Paul Lalli


Report this thread to moderator Post Follow-up to this message
Old Post
Paul Lalli
08-19-07 03:02 AM


Re: unfamiliar array reference
>>>>> "Paul" == Paul Lalli <mritty@gmail.com> writes:
 

Paul> Is that seriously from the book?  UGH.  Just declare $array_ref in the
Paul> proper scope, and there's no need to take a reference to a dereference
Paul> of the reference.

Yes there is.

Paul> while (my $array_ref  = $sth1->fetchrow_arrayref) {
Paul>     push @stash, $array_ref;
Paul> }

Your code breaks on older versions of DBI, for which the book was written.
In older versions of DBI, the value of $array_ref would have been
the same for each row returned.  There was this clause in "perldoc DBI":

Note that the same array reference is returned for each fetch, so don't
store the reference and then use it after a later fetch. Also, the elements
of the array are also reused for each row, so take care if you want to take
a reference to an element.

Yes, DBI has matured since the book, but I wouldn't jump to conclusions abou
t
the validity of the code in the book.  After all, Tim Bunce co-wrote the boo
k,
and there's nobody on the planet who knows more about DBI.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training
!

Report this thread to moderator Post Follow-up to this message
Old Post
Randal L. Schwartz
08-19-07 03:02 AM


Re: unfamiliar array reference
On Aug 18, 10:03 pm, mer...@stonehenge.com (Randal L. Schwartz) wrote: 
>
> Paul> Is that seriously from the book?  UGH.  Just declare $array_ref in t
he
> Paul> proper scope, and there's no need to take a reference to a dereferen
ce
> Paul> of the reference.
>
> Yes there is.
>
> Paul> while (my $array_ref  = $sth1->fetchrow_arrayref) {
> Paul>     push @stash, $array_ref;
> Paul> }
>
> Your code breaks on older versions of DBI, for which the book was written.
> In older versions of DBI, the value of $array_ref would have been
> the same for each row returned.  There was this clause in "perldoc DBI":
>
>   Note that the same array reference is returned for each fetch, so don't
>   store the reference and then use it after a later fetch. Also, the eleme
nts
>   of the array are also reused for each row, so take care if you want to t
ake
>   a reference to an element.

Yeesh.  I guess I'm fortunate to have only dealt with newer versions
of DBI.pm. :-)

Thanks for the history lesson.

Paul Lalli


Report this thread to moderator Post Follow-up to this message
Old Post
Paul Lalli
08-19-07 12:58 PM


Re: unfamiliar array reference
On Aug 18, 7:58 pm, mri...@gmail.com (Paul Lalli) wrote:

snip

>
> Is that seriously from the book?  UGH.  Just declare $array_ref in the
> proper scope, and there's no need to take a reference to a dereference
> of the reference.
>
> while (my $array_ref  = $sth1->fetchrow_arrayref) {
>     push @stash, $array_ref;
>
> }


Great - this worked fine.

>
> In this specific example, "data" is the sixth column in the SELECT
> query.  You would therefore access it by $array_ref->[5].
>

No luck here, I could not retrieve anything (example code below).


> I would generally recommend you use the fetchrrow_hashref method
> rather than fetchrow_arrayref, so that you can refer to the column by
> name.  This will prevent bugs in your code if you later change the
> query to add or remove columns.  With fetchrow_hashref, the return
> value is a reference to a hash rather than to an array:
>
> while (my $hash_ref = $sth1->fetchrow_hashref()) {
>     print $hash_ref->{data} . "\n";
>
> }

I was able to replicate this and also do a push to an array, but
again, I could not retrieve rows.


> I agree with other posters - you should read:
> perldoc perlref
> perldoc perlreftut
> perldoc perllol
> perldoc perldsc
>
> Paul Lalli

Thanks to all who suggested these perldocs - the perlreftut and
perllol were especially helpful.

I've learned more about references and also about scoping of variables
- now I'm doing "use strict" and it took a while to make it work
here.
A side question: why is it necessary to declare "our @variable" more
than once in a program?

The main problem is that I still can't retrieve data at will.
See below:

First, as an array - I tried commented-out options one at a time.
Msg is error message from Perl.

$sth1->execute();

while (my $array_ref = $sth1->fetchrow_arrayref) {
push ((our @stash), $array_ref);  ##copy array contents
}

#use Data::Dumper 'Dumper';
#    print Dumper our @stash ; #Msg: $VAR19586 = $VAR1;

###dump stash contents
foreach my $array_ref (our @stash ) {
# print "Row: $array_ref->[5]\n"; #Msg:Use of uninitialized value in
concatenation
#  print $array_ref->[5]; #Msg: Use of uninitialized value in
concatenation
print "Row:  @$array_ref\n"; #works, prints entire rows (from book)
}

foreach my $row (our @stash) {
# print "DATA: $row->[5]\n";  #Msg: Use of uninitialized value in
concatenation or string
# print "DATA: @$row->[5]\n"; #Msg: Use of uninitialized value in join
or string
#}

Now as a hash, which is what I would prefer, for the reasons stated by
Paul.

$sth1->execute();

while (my $hash_ref = $sth1->fetchrow_hashref()) {
#print $hash_ref->{data} . "\n";  # works, prints data
push our @stash, [ %$hash_ref ];  #works, copies hash contents
}

#use Data::Dumper 'Dumper';
#    print Dumper our @stash; #showed good results (see below)

foreach my $hash_ref (our @stash ) {
#print "Row: %$hash_ref\n";  #Msg:  Row: %ARRAY(0x13f88d44)
#print "Row: $hash_ref\n"; #Msg:  Row: %ARRAY(0x13f88d44)
#print %$hash_ref . "\n"; #Msg: 'Can't coerce array into hash at'
}

from hash Data Dumper:
$VAR790 = [
'time_stamp',
'Mon Mar 05 2007 11:07:11',
'message_event',
'MESSAGE OUT',
'message_no',
'12101589',
'data',
' MSH|^~\\&|HUB|HOSP.MED.XXXX.EDU|PM3.0|HOSP.MED.XXXX.EDU|200
',A|AA|9}|MESSAGE ACCEPTED||
'message_index',
'36314470'
];
$VAR791 = [
'time_stamp',
'Mon Mar 05 2007 11:07:11',
etc.....

What am I doing wrong?
Thanks for all the help.

Peter Link


Report this thread to moderator Post Follow-up to this message
Old Post
petelink1@yahoo.com
08-24-07 09:01 AM


Re: unfamiliar array reference
On 8/24/07, Paul Lalli <mritty@gmail.com> wrote:
snip
> 'our', like 'my', is lexically scoped.  Its effects are terminated
> when the innermost enclosing block ends.  So if you're using the same
> package variable in two different blocks, you have to use 'our' in
> each of them:
snip
> Your syntax for 'our' is confusing at best.  Just declare it once, at
> the very top of your program.
snip
> Again.  Stop using 'our' all over the place.  Declare your variables
> once, at the beginning of your program, if it's being used throughout
> the program.
snip

I can't say that I agree with the advice to declare all of your our
variables once at the top of your program.  To my way of thinking this
defeats the purpose of having the our function*.  I have a
once-per-function rule for our; if a function needs to use a global
variable, then it has to request it.  This means that when you come
back to the code a year later, and are looking at just that one
function, you can easily see that the variable is special (i.e. used
by many functions).  That said, the code you were referring to was
definitely overusing our.  It doesn't need to be attached to every
reference to the variable.

* yes, the variable is still visible to all packages in the same file
without having to be fully qualified, but I consider that aspect of
our a misfeature.

Report this thread to moderator Post Follow-up to this message
Old Post
Chas Owens
08-25-07 12:01 AM


Re: unfamiliar array reference
Paul Lalli wrote:
> 'our', like 'my', is lexically scoped.  Its effects are terminated
> when the innermost enclosing block ends.  So if you're using the same
> package variable in two different blocks, you have to use 'our' in
> each of them:

'our' is not lexically scoped; it is package scoped.  Once you declare a var
iable using 'our' you may use it anywhere in the package.  Think of it as an
 alias to the fully-qualified variable.  A variable declare via 'our' in one
 package is independent of
a variable of the same name in another package.

See `perldoc -f our` for more details.

#!/usr/bin/perl

use strict;
use warnings;

package Foo;
our $bar = 'Foo's bar';  # $bar is an alias to $Foo::bar
print "$bar\n";

sub bar {
print "Foo::bar sub: $bar\n";
}

package main;
our $bar = 'main's bar';  # $bar is an alias to $main::bar or $::bar;
print "$bar\n";

print "$Foo::bar\n";
print "$main::bar\n";
print "$::bar\n";

Foo::bar();

__END__



--
Just my 0.00000002 million dollars worth,
Shawn

"For the things we have to learn before we can do them, we learn by doing th
em."
Aristotle

"If you think Terrans are comprehensible, you don't understand them."
Great Fang Talphon

Report this thread to moderator Post Follow-up to this message
Old Post
Mr. Shawn H. Corey
08-25-07 12:01 AM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

PERL Beginners archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 01:12 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.