Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > scope of MY in FOREACH with global array

Reply
Thread Tools

scope of MY in FOREACH with global array

 
 
Bill
Guest
Posts: n/a
 
      07-17-2004
I've been programming perl for a while now and I can't believe something so
simple is confusing me. Take a look at the following code:

-------------------------
#!/usr/bin/perl -w

# global array definition
my @array = ("a","b","c");

sub print_array {
foreach my $element (@array) {
$element .= "9";
print $element . "\n";
}
}

for ($i = 0; $i < 3; $i++) {
&print_array();
}
------------------------

The output is as follows:

a9
b9
c9
a99
b99
c99
a999
b999
c999

What I expected was:

a9
b9
c9
a9
b9
c9
a9
b9
c9

I thought that "my" would make a copy of each array element whose scope was
limited to the subroutine in which it was defined. But it seems that
modifying the elements locally is modifying them in the global array as
well. What am I missing here?

-Bill


 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      07-17-2004
Bill wrote:
> -------------------------
> #!/usr/bin/perl -w
>
> # global array definition
> my @array = ("a","b","c");
>
> sub print_array {
> foreach my $element (@array) {
> $element .= "9";
> print $element . "\n";
> }
> }
>
> for ($i = 0; $i < 3; $i++) {
> &print_array();
> }
> ------------------------

[...]
> I thought that "my" would make a copy of each array element whose
> scope was limited to the subroutine in which it was defined. But it
> seems that modifying the elements locally is modifying them in the
> global array as well. What am I missing here?


Simple. The loop variable ($element in this case, $_ by default) is an
_alias_ of the array element, not a copy. That means, when you write
$element .= "9" this has the same effect as using $array[$CURRENTINDEX] .=
"9". Otherwise it would be impossible to use such a loop to alter the array
elements. And because @array is global those changes stick.

Now, the scoping rule for my effect $element. That means, if there were a
global variable $element, then that global variable would have been
protected from undesired changes by the "my $element".

In short: the "my" localizes the variable $element, but not the variable
@array.

jue



 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      07-17-2004
"Bill" <(E-Mail Removed)> writes:

> foreach my $element (@array) {


> I thought that "my" would make a copy of each array element


No, the for-loop interator variable is an _alias_ not a _copy_ of an
element in the list over which you are iterating. Changes made to the
loop iterator variable $elmenet are, therefore, changes to acual
elements of @array.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      07-17-2004
On Sat, 17 Jul 2004, Bill wrote:

> I've been programming perl for a while now and I can't believe something so
> simple is confusing me. Take a look at the following code:
>
> -------------------------
> #!/usr/bin/perl -w
>
> # global array definition
> my @array = ("a","b","c");
>
> sub print_array {
> foreach my $element (@array) {
> $element .= "9";
> print $element . "\n";
> }
> }
>
> for ($i = 0; $i < 3; $i++) {
> &print_array();
> }
> ------------------------
>
> I thought that "my" would make a copy of each array element whose scope was
> limited to the subroutine in which it was defined. But it seems that
> modifying the elements locally is modifying them in the global array as
> well. What am I missing here?


You're missing the difference between a value in memory and the name that
refers to it. The 'symbol' (for lack of a better term here) called
$element is is scoped to only within the foreach loop. However, that
symbol represents an alias to the values in @array. Because it's an
alias, not a copy, you are directly modifying @array. If you were to try
to access $element outside the foreach loop, it would have no value.

In short, the 'name' $element is what's scoped, not the memory location it
represents.

Paul Lalli
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 1 10-25-2006 06:50 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 0 10-25-2006 01:04 PM
References to an array in a foreach David K. Wall Perl Misc 14 10-19-2004 04:29 AM
Idiom for array index that I'm foreach'ing over? Tim Shoppa Perl Misc 45 12-23-2003 04:30 PM
bug in lexically scoped array not reset in foreach loop Gavin Sherlock Perl Misc 1 12-10-2003 10:36 PM



Advertisments