Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Foreach & scalar ref: break of way that it is suposed to work!

by gmpassos (Priest)
on Apr 08, 2003 at 19:32 UTC ( #249049=perlmeditation: print w/replies, xml ) Need Help??

I was reading the node "Surpised by foreach iterator limitation", than I made some test codes to try to make the idea in the node works.

What the user want to do is use the $hash{key} as the string receiptor of the foreach, something like that:

foreach $hash{key} (@array){ ## The value of $hash{key} will be the $array[x] value. ## ... }
But this code can't be compiled since foreach only accept a scalar to receive the array string. Thinking in that I made a code that use a scalar variable that has a direct access to the value of the key in the hash:

my %hash = ( key => 'value'); my $k_ref = \$hash{key} ; *{'main::val'} = $k_ref ; ## To avoid $$k_ref print "val: <$val>\n" ; print "key: <$hash{key}>\n" ; $val = 'test' ; print "val: <$val>\n" ; print "key: <$hash{key}>\n" ;
Soo now I have a scalar variable that I can read and write to it and affect the value of the key in the hash (a scalar linked to the value of the key). Now I tried to use the same scalar in the foreach:
my %hash = ( key => 'value'); my $k_ref = \$hash{key} ; *{'main::val'} = $k_ref ; my @array = (0..5) ; print "val: <$val>\n" ; print "key: <$hash{key}>\n" ; foreach $val ( @array ) { print "for>> val: <$val>\n" ; print "for>> key: <$hash{key}>\n" ; } print "val: <$val>\n" ; print "key: <$hash{key}>\n" ;
But running the code you can see that it doesn't work like you want. The output inside the foreach will be:
for>> val: <0> for>> key: <value> for>> val: <1> for>> key: <value> for>> val: <2> for>> key: <value> ...
And not:
for>> val: <0> for>> key: <0> for>> val: <1> for>> key: <1> for>> val: <2> for>> key: <2> ...
Why this hapens?! Because when you put a $scalar in the foreach to reaceive the string, you are accessing the scalar inside the array directly, and not copying the content to the scalar! This is why when you change the value of the scalar the array is changed too:
my @array = (1..5) ; print "@array\n" ; foreach my $array_i ( @array ) { $array_i *= 10 ;} print "@array\n" ;
And this is a good thing, since is a speed improvement too. I know that the idea to affect the value of a key with the foreach is not a code that is useful, since you can make it explicit:
my %hash = ( key => 'value'); my @array = (0..5) ; foreach my $val ( @array ) { $hash{key} = $val ; print "for>> val: <$val>\n" ; print "for>> key: <$hash{key}>\n" ; }
But you can see that Perl is very powerful, specially with variables. only using other languages to see that... ;-P

Graciliano M. P.
"The creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: Foreach & scalar ref: break of way that it is suposed to work! (local)
by tye (Sage) on Apr 08, 2003 at 20:09 UTC

    Try this:

    my %hash = ( key => 'value'); my $k_ref = \$hash{key} ; *{'main::val'} = $k_ref ; ## To avoid $$k_ref print "val: <$val>\n" ; print "key: <$hash{key}>\n" ; { local( $val )= 'test' ; print "val: <$val>\n" ; print "key: <$hash{key}>\n" ; }
    and note that it produces
    val: <value> key: <value> val: <test> key: <value>
    and you might see the light.

    foreach does an implicit local which does a rough equivalent of

    my $saved= *main::val{SCALAR}; *main::val= do { my $new; \$new }; ... *main::val= $saved;
    That is, it copies off and saves the reference to the variable rather than the value contained in the variable.

                    - tye
Re: Foreach & scalar ref: break of way that it is suposed to work!
by shotgunefx (Parson) on Apr 08, 2003 at 20:08 UTC
    Internally you can hv_fetch on a hash and it will retreive an assignable scalar lvalue for $hash{key} which is why I assumed it would work. I would think it's more of a parser issue. I knew magic vars wouldn't work from the docs (I assume as it is optimized it does call magic on the value)

    -Lee

    "To be civilized is to deny one's nature."
Re: Foreach & scalar ref: break of way that it is suposed to work!
by Juerd (Abbot) on Apr 08, 2003 at 22:41 UTC
      The entire issue is that you can local $foo{bar}.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://249049]
Approved by dragonchild
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2020-02-29 01:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What numbers are you going to focus on primarily in 2020?










    Results (128 votes). Check out past polls.

    Notices?