tr operator weirdness

B

Bernhard Singer

I just tried something like the following - can someone tell me what is
going on there? To my knowledge, tr should be changing $_, not @list.

my @list = ("foo bar", "say cheese", "granny smith");

my %hash;

for (@list) { $hash{$_} = rand(1); }

for (@list) {
tr/ /_/; # <==== what the hell? why is this changing the values
# in @list?
print "$_\n";
}

for (@list) {
die "Help! $_\n" unless defined $hash{$_};
print $_, ": ", $hash{$_}, "\n";
}
 
X

xhoster

Bernhard Singer said:
I just tried something like the following - can someone tell me what is
going on there?

Yes. Not only can someone tell you that, but something can tell
you that as well. Like the documentation for Perl.

perldoc perlsyn, look for "Foreach Loops"

....
for (@list) {
tr/ /_/; # <==== what the hell? why is this changing the values
# in @list?

Because $_ *is* the values in @list.

Xho
 
P

Paul Lalli

Bernhard said:
I just tried something like the following - can someone tell me what is
going on there? To my knowledge, tr should be changing $_, not @list.

Your knowledge is wrong.
my @list = ("foo bar", "say cheese", "granny smith");

my %hash;

for (@list) { $hash{$_} = rand(1); }

for (@list) {
tr/ /_/; # <==== what the hell? why is this changing the values
# in @list?

Because a for/foreach loop creates *aliases* to the elements in @list,
not copies.
print "$_\n";
}

You need to read about foreach loops. They are documented in
perldoc perlsyn

Here's an exerpt:
LABEL foreach VAR (LIST) BLOCK
If any element of LIST is an lvalue, you can modify it by
modifying VAR inside the loop. Conversely, if any element
of LIST is NOT an lvalue, any attempt to modify that element
will fail. In other words, the "foreach" loop index
variable is an implicit alias for each item in the list that
you're looping over.


Paul Lalli
 
G

Gunnar Hjalmarsson

Bernhard said:
I just tried something like the following - can someone tell me what is
going on there? To my knowledge, tr should be changing $_, not @list.

my @list = ("foo bar", "say cheese", "granny smith");

my %hash;

for (@list) { $hash{$_} = rand(1); }

for (@list) {
tr/ /_/; # <==== what the hell? why is this changing the values
# in @list?
print "$_\n";
}

The @list values are changed because $_ is an alias for respective @list
element. Read about the foreach loop in "perldoc perlsyn".
 
B

boyd

Bernhard Singer said:
I just tried something like the following - can someone tell me what is
going on there? To my knowledge, tr should be changing $_, not @list.

my @list = ("foo bar", "say cheese", "granny smith");

my %hash;

for (@list) { $hash{$_} = rand(1); }

for (@list) {
tr/ /_/; # <==== what the hell? why is this changing the values
# in @list?
print "$_\n";
}

for (@list) {
die "Help! $_\n" unless defined $hash{$_};
print $_, ": ", $hash{$_}, "\n";
}

Ah... familiar with this 'got bitten'. The @list elements are being
passed as references to tr through $_, so that each element in @list
gets changed. This is a feature in perl. Several ways to prevent this;
one way:

for(@list){
my $val = $_;
$val =~ tr/ /_/;
print "$val\n";
}

Boyd
 
B

Bernhard Singer

Thanks for the help. Seems I have missed out on a basic property of the
for-loop. In my defense, searching perlsyn did not occur to me because I
suspected perlop.
 
P

Paul Lalli

Bernhard said:
Thanks for the help. Seems I have missed out on a basic property of the
for-loop. In my defense, searching perlsyn did not occur to me because I
suspected perlop.

Please quote relevant material when posting a reply. Thank you.

To confirm that it's the for loop, not the tr/// that was having the
unexpected result, change
tr/_/ /;
to
$_ = "foobar";
and then look at the array again.

Paul Lalli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top