develooper Front page | perl.beginners | Postings from October 2009

Re: Need explanation about this code.

Thread Previous | Thread Next
From:
Rob Coops
Date:
October 9, 2009 04:06
Subject:
Re: Need explanation about this code.
Message ID:
867476850910090406m2632cf32qc602c80e6beea680@mail.gmail.com
On Fri, Oct 9, 2009 at 9:58 AM, Raheel Hassan <raheel.hassan@gmail.com>wrote:

> Thanks Jim for a nice reply, could you explain what
> push(@$temp_table,$ref->[$i]); is doing. in the first code.
>
> In the second @_= $dbh where as in the if command $_ is getting the values
> from this default array. Then how it can return \%s..........in the last
> statement.
>
>
>
> On Thu, Oct 8, 2009 at 6:54 PM, Jim Gibson <jimsgibson@gmail.com> wrote:
>
> > On 10/8/09 Thu  Oct 8, 2009  9:00 AM, "Raheel Hassan"
> > <raheel.hassan@gmail.com> scribbled:
> >
> > > Hello,
> > >
> > > I have problems in understanding $#{@$ use ?????
> > >
> > > 1- my $ref = $$temp_sth -> fetchall_arrayref({});
> > >     for(my $i=0; $i <= $#{@$ref}; $i++) {
> >
> > For any array @a, the largest index is given by $#a.
> >
> > $ref is a reference to an array, as returned by the fetchall_arrayref
> > method.
> >
> > @{$ref} is the array returned.
> >
> > Therefore, $#{@$ref} is the largest index of the returned array, i.e.,
> the
> > index of the last element of the array.
> >
> >
> > >     push(@$temp_table,$ref->[$i]);}
> > >
> > > Can some one explain the under given function.
> >
> > It looks like a function that queries a database, getting all of the data
> > from a table called "Sensors". Then for each row in that table, checks
> the
> > value of the column labeled "StatusID", and, if the value of that column
> is
> > "1", adds an entry to a hash with the contents of the "IP" column as key,
> > and the value taken from the column "SensorID". The function returns a
> > list,
> > consisting of a reference to the hash and the value of the $error
> variable,
> > which will be 0 if no error occurred, and 1 if an error did occur.
> >
> > > 2- sub buildSensorsHashtable
> > >     {
> > >
> > >    my ($dbh) = @_;
> > >    my $error = 0;
> > >
> > >          my $query = "SELECT * FROM Sensors";
> > >          my $sth = $dbh->prepare($query);
> > >          if(!$sth || !($sth->execute())) { $error = 1 ;
> > >  }
> > >
> > >          my $ref = $sth->fetchall_arrayref({});
> > >          my %s;
> > >          my @s = @$ref;
> > >     foreach (@s)
> > >     {
> > >         if($_->{"StatusID"} eq "1") { $s{$_->{"IP"}} =
> $_->{"SensorID"};
> > }
> > >     }
> > >
> > >     return (\%s,$error);
> > >
> > > 3- Which is the best tool for debuging perl programs having CGI
> support.
> > I
> > > used DDD but that does not support CGI.
> >
> > Debugging CGI programs can be difficult. You need access to the HTTP
> logs.
> > You can help yourself by following the advice given in the FAQ "How can I
> > get better error messages from a CGI program?" (see 'perldoc -g CGI').
> Try
> > to set up a test environment, either by executing the CGI program from
> the
> > command line (by supplying the various parameters needed) or by running
> the
> > program first on a local server where you have access to the logs.
> >
> > Good luck.
> >
> >
> >
>

Hi Raheel,

I can try to explain the following: push(@$temp_table,$ref->[$i]);}

1)
Push you most likely know, push a variable onto an array (append at the end
of the array). Since as Jim explained $ref is a reference to an array and $i
will contain the counter used by the for loop. $ref->[$i] asked the array
that $ref is pointing to to return the value at position $i.
So "push ( @$temp_table, $ref->[$i] )" does nothing more then push the value
returned by $ref->[$i] onto the array referenced by $temp_table.

2)
Please note the following line:
my %s;

Since in line:
if($_->{"StatusID"} eq "1") { $s{$_->{"IP"}} = $_->{"SensorID"}; }

You are checking to see if $_->{"Status_ID} is equal to 1 and when it is you
are in hash %s setting a key $_->{"IP"} with a value of $_->{"SensorID"}
%s will contain the following
Key                   Value
$_->{"IP"}           $_->{"SensorID"}
For every entry in $_ that has a $_->{"Status_ID} which is equal to 1

In your return statement you are returning two things:
return (\%s,$error);
The first being a reference to the hash %s and the second the scalar $error.
Putting a \ in front of a variable like in your \%s causes Perl to return a
reference to the variable instead of the variable. You will often see this
done in return statements in Perl because of the way Perl internally works.
When Perl returns a variable like $error from a sub to where ever this sub
is called from what Perl does is make a copy of variable $error, and it
leaves the memory space used by $error for the Perl internals to clean up.
Now with $error which will contain a string of a few bytes this is not a
major problem. But with the hash %s this could be many megabytes of data
being copied from one location in memory to another. Leaving the old copy
for Perl to clean up which might be done right away or not for a while...
which could obviously cause problems with available memory.
Returning a reference to a hash Perl just hands over the memory address
where the hash can be found, it does not copy the original hash thus it
doesn't, not even for a short time, copy the entire hash. The added bonus is
that it requires less work and thus less time making your program that
little bit faster. You will not notice this unless you are returning
hundreds of thousands of large variables but still all little bits help.

Regards,

Rob

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About