Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

'my' declaration in a 'while' statement

4 views
Skip to first unread message

Peter Cornelius

unread,
Sep 11, 2001, 12:24:51 PM9/11/01
to
A recent thread on Per Monks related a problem with a statement like...

my $thing = $_ while (<DATA>);

I would expect that $thing would end up with whatever the last record in
DATA was, but it seems to be inaccessible. Here's a little snippet of code
and output that I'm hoping someone here can explain to me.

use strict;
use warnings;
use Devel::Peek;

my $thing = $_ while (<DATA>);

print Dump $thing;
print "<<$thing>>\n";

__DATA__
Eep op orp ah ah
Goip Gorp
Grok

The output is

SV = PV(0x1a7ebb0) at 0x1a73028
REFCNT = 1
FLAGS = (PADBUSY,PADMY)
PV = 0x1a7017c "Grok\n"\0
CUR = 5
LEN = 18
Use of uninitialized value in concatenation (.) or string at mymymy.pl line
8, <
DATA> line 3.
<<>>

The things I find interesting is that the POK, pPOK flags are missing and
that the last line of data is in the PV field. I also notice that the
string length has grown to accommodate the longest line in data so I think
that each line was assigned to '$thing' but I can't print it out. A couple
of interesting mods that make this 'work' is if the 'my $thing' decl happens
before the 'while' statement or if it is a package variable. Is this some
kind of scoping issue?

Sam Kington

unread,
Sep 12, 2001, 9:19:10 PM9/12/01
to
Peter Cornelius wrote:
>
> A recent thread on Per Monks related a problem with a statement like...
>
> my $thing = $_ while (<DATA>);
>
> I would expect that $thing would end up with whatever the last record in
> DATA was, but it seems to be inaccessible.
[...]

Does the same thing happen if you say

while (<DATA>) {
my $thing = $_;
}

?

I would imagine the two blocks were equivalent.

Sam
--
Home page: http://www.illuminated.co.uk/
Convert ZIPs to Mac format: http://www.illuminated.co.uk/macifyzip/
In Nomine Cookbook: http://www.illuminated.co.uk/innomine/
"... After all, all he did was string together a lot of old, well-known
quotations." - H. L. Mencken, on Shakespeare

John Porter

unread,
Sep 12, 2001, 10:44:23 PM9/12/01
to
Peter Cornelius wrote:
> my $thing = $_ while (<DATA>);
>
> SV = PV(0x1a7ebb0) at 0x1a73028
> REFCNT = 1
> FLAGS = (PADBUSY,PADMY)
> PV = 0x1a7017c "Grok\n"\0
> CUR = 5
> LEN = 18
> Use of uninitialized value in concatenation (.) or string at mymymy.pl line
> 8, <
> DATA> line 3.
> <<>>
>
> Is this some kind of scoping issue?

Possibly... perhaps it's strange effect of having a statement which
is executed multiple times without being in a nested scope.
Perhaps it has something to do with the fact that perl reuses pad
variables. And/or the fact that the final value of $_ from the while
is undef, even though it doesn't get assigned to $thing.

--
John Porter

Malcolm Dew-Jones

unread,
Sep 13, 2001, 4:59:33 AM9/13/01
to
Sam Kington (s...@illuminated.co.uk) wrote:

: Peter Cornelius wrote:
: >
: > A recent thread on Per Monks related a problem with a statement like...
: >
: > my $thing = $_ while (<DATA>);
: >
: > I would expect that $thing would end up with whatever the last record in
: > DATA was, but it seems to be inaccessible.
: [...]

: Does the same thing happen if you say

: while (<DATA>) {
: my $thing = $_;
: }

: ?

: I would imagine the two blocks were equivalent.

But the first form is not called a block, it's called a "modifier". If
you do something like

my $x = 'YES' if 1==1;
print $x;

then you'll see that the scope of the my extends beyond the if (which
would not be true in a block).

Martien Verbruggen

unread,
Sep 12, 2001, 9:52:52 PM9/12/01
to
On Thu, 13 Sep 2001 02:19:10 +0100,
Sam Kington <s...@illuminated.co.uk> wrote:

> Peter Cornelius wrote:
>>
>> my $thing = $_ while (<DATA>);

> while (<DATA>) {
> my $thing = $_;
> }

> I would imagine the two blocks were equivalent.

No, they aren't. In the first case, the lexical scope of $thing
continues after the while loop, in the second it doesn't. In the OP's
example, $thing is accessible on the line after the loop (but
undefined), in your case it isn't accessible outside of the block.
The op tree generated for both pieces of code is different.

It smells like a bug to me.

Martien
--
Martien Verbruggen |
Interactive Media Division | Never hire a poor lawyer. Never buy
Commercial Dynamics Pty. Ltd. | from a rich salesperson.
NSW, Australia |

0 new messages