Home > Archive > PERL Beginners > October 2006 > Scope
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| John Ackley 2006-10-01, 9:58 pm |
| simple scope question
when is a global not a global?
or how to get a value from inside a while() to the outside?
two tests-extracted from much large program to show my problem
-------------------- test 1 --------------------------------
my $count;
my $service;
while( ($service) = $SERVICE->fetchrow_array ) {
$count++;
print "count $count service.number <$service>\n";
}
print "service.number <$service>\n";
produces output:
$ ./test.pl
count 1 service.number <229>
Use of uninitialized value at ./test.pl line 26.
service.number <>
note:same results with/without () around $service
----------------- test 2 ---------------------------------
my $count;
my $servicenumber;
while( my ($service) = $SERVICE->fetchrow_array ) {
$count++;
print "count $count service.number <$service>\n";
$servicenumber = $service;
}
print "service.number <$servicenumber>\n";
(note: the "my" on $service was required by strict)
produces desired result:
$ ./test.pl
count 1 service.number <229>
service.number <229>
----------------------------------------------
header of test.pl is
#! /usr/bin/perl -w
use strict;
use DBI;
my $driver = DBI->install_driver('mysql') or die;
my $max = DBI-> connect('DBI:mysql:database=max','max','
pass') or die;
my $SERVICE = $max->prepare("\
SELECT number
FROM service
WHERE state = 0
----------------------------------------------------
$ perl -v
This is perl, version 5.005_03 built for i386-freebsd
AND d03 = ?") or die;
$SERVICE->execute('0020a6-5a83b4') or die;
| |
| Paul Lalli 2006-10-01, 9:58 pm |
| John Ackley wrote:
> simple scope question
> when is a global not a global?
> or how to get a value from inside a while() to the outside?
>
> two tests-extracted from much large program to show my problem
> -------------------- test 1 --------------------------------
> my $count;
> my $service;
>
> while( ($service) = $SERVICE->fetchrow_array ) {
> $count++;
> print "count $count service.number <$service>\n";
> }
> print "service.number <$service>\n";
>
> produces output:
> $ ./test.pl
> count 1 service.number <229>
> Use of uninitialized value at ./test.pl line 26.
> service.number <>
> note:same results with/without () around $service
This is all exactly as expected. The first time your while()
conditional is evaluated, $service gets the value 229. 229 is true, so
the while() loop executes. The second time the while() conditional is
evaluated, fetchrow_array returns undefined, so $service gets the
undefined value. Undefined is false, so the loop is not executed, and
terminates. That's why $service has undef after the end of the loop.
> ----------------- test 2 ---------------------------------
> my $count;
> my $servicenumber;
>
> while( my ($service) = $SERVICE->fetchrow_array ) {
> $count++;
> print "count $count service.number <$service>\n";
> $servicenumber = $service;
> }
> print "service.number <$servicenumber>\n";
> (note: the "my" on $service was required by strict)
>
> produces desired result:
> $ ./test.pl
> count 1 service.number <229>
> service.number <229>
Right. Because you set $servicenumber to $service only during the
execution of the while loop - when, by definition, $service must have a
true value. The second time the conditional is executed, $service gets
undef, which causes the loop to terminate immediately - $servicenumber
is not set, and so remains whatever it was.
I'm not sure what your actual question is. If you're asking for an
explanation of the actual results, I hope I've provided it. If you're
asking for a better way.... I really don't think there is.
Paul Lalli
| |
| Charles K. Clarkson 2006-10-02, 3:58 am |
| John Ackley wrote:
: while( ($service) = $SERVICE->fetchrow_array ) {
According to the DBI docs:
"If there are no more rows or if an error occurs,
then fetchrow_array returns an empty list."
When a value is returned, $service is set to that value.
When we get to the end of the list, () is returned and
$service is set to the undefined value. Since it tests
false, the while loop stops with $service set to an undefined
value.
You can see this in the following script.
use strict;
use warnings;
use Data::Dumper 'Dumper';
my $service;
($service) = ();
print Dumper $service;
__END__
HTH,
Charles K. Clarkson
--
Mobile Homes Specialist
Free Market Advocate
Web Programmer
254 968-8328
Don't tread on my bandwidth. Trim your posts.
| |
| nobull67@gmail.com 2006-10-02, 7:58 am |
| Paul Lalli wrote:
> John Ackley wrote:
[color=darkred]
> The second time the while() conditional is
> evaluated, fetchrow_array returns undefined, so $service gets the
> undefined value. Undefined is false, so the loop is not executed, and
> terminates.
Actually that's not true.
The second time the while() conditional is evaluated, fetchrow_array
returns an empty list.
Because there are now more variables on the LHS of the assignment than
in the list $service gets the undefined value.
The scalar context return value of a list assignment is the number of
elements in the RHS list. This is zero. Zero is false so the loop is
not executed, and terminates.
If fetchrow_array had returned undef (i.e. a list containing one
element that was the undef value) then $service would still have been
undef but the loop would not have terminated.
> That's why $service has undef after the end of the loop.
That bit is right!
| |
| Paul Lalli 2006-10-02, 7:58 am |
| nobull67@gmail.com wrote:
> Paul Lalli wrote:
>
>
>
> Actually that's not true.
>
> The second time the while() conditional is evaluated, fetchrow_array
> returns an empty list.
>
> Because there are now more variables on the LHS of the assignment than
> in the list $service gets the undefined value.
>
> The scalar context return value of a list assignment is the number of
> elements in the RHS list. This is zero. Zero is false so the loop is
> not executed, and terminates.
>
> If fetchrow_array had returned undef (i.e. a list containing one
> element that was the undef value) then $service would still have been
> undef but the loop would not have terminated.
Huh. Well I'll be darned. You are absolutely correct. And in case
anyone else is/was , here's a script to illustrate:
#!/usr/bin/perl
use strict;
use warnings;
my $i = 0;
while (my ($foo) = func($i)) {
print "Foo: '$foo'\n";
$i++;
}
sub func {
my $val = shift;
return ('first', undef, 2)[$val];
}
__END__
The first time through, func will return 'first', then the undefined
value, then the integer 2, and finally the empty list. Output of this
script:
Foo: 'first'
Use of uninitialized value in concatenation (.) or string at ./clpm.pl
line 8.
Foo: ''
Foo: '2'
Thanks for the corrections and information!
Paul Lalli
| |
| Derek B. Smith 2006-10-02, 6:59 pm |
| -- "Charles K. Clarkson" <cclarkson@htcomp.net> wrote:
> John Ackley wrote:
>
>
> : while( ($service) = $SERVICE->fetchrow_array ) {
>
> According to the DBI docs:
>
> "If there are no more rows or if an error occurs,
> then fetchrow_array returns an empty list."
>
> When a value is returned, $service is set to
> that value.
> When we get to the end of the list, () is returned
> and
> $service is set to the undefined value. Since it
> tests
> false, the while loop stops with $service set to an
> undefined
> value.
>
> You can see this in the following script.
>
> use strict;
> use warnings;
> use Data::Dumper 'Dumper';
>
> my $service;
>
> ($service) = ();
>
> print Dumper $service;
>
John,
For a complete understanding of scope (not listerine)
: )
please read the following:
http://perl.plover.com/local.html#2...zed_Filehandles
and
http://www.perlmonks.org/?node_id=564448
Wow...opened my eyes and I now fully understand global
and non global variables.
________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
| |
| Chad Perrin 2006-10-02, 6:59 pm |
| On Mon, Oct 02, 2006 at 07:15:38AM -0700, Derek B. Smith wrote:
>
> For a complete understanding of scope (not listerine)
> : )
> please read the following:
> http://perl.plover.com/local.html#2...zed_Filehandles
>
> and
> http://www.perlmonks.org/?node_id=564448
>
> Wow...opened my eyes and I now fully understand global
> and non global variables.
Hah. That's the PerlMonks thread I tried to send to the list
previously, and accidentally replied directly to the OP rather than
sending to the list. Being the lazy soul I am, I didn't bother to
resend.
I'm glad *someone* sent it to the list at large, in case it's useful to
more than just the OP.
--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
unix virus: If you're using a unixlike OS, please forward
this to 20 others and erase your system partition.
|
|
|
|
|