tr operator weirdness

Discussion in 'Perl Misc' started by Bernhard Singer, Dec 14, 2006.

  1. 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";
    }
     
    Bernhard Singer, Dec 14, 2006
    #1
    1. Advertising

  2. Bernhard Singer

    Guest

    Bernhard Singer <> wrote:
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Dec 14, 2006
    #2
    1. Advertising

  3. Bernhard Singer

    Paul Lalli Guest

    Bernhard Singer wrote:
    > 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
     
    Paul Lalli, Dec 14, 2006
    #3
  4. Bernhard Singer wrote:
    > 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".

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Dec 14, 2006
    #4
  5. Bernhard Singer

    boyd Guest

    In article <4581a0d6$0$27609$-online.net>,
    Bernhard Singer <> wrote:

    > 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
     
    boyd, Dec 14, 2006
    #5
  6. 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.
     
    Bernhard Singer, Dec 14, 2006
    #6
  7. Bernhard Singer

    Paul Lalli Guest

    Bernhard Singer wrote:
    > 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
     
    Paul Lalli, Dec 14, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wayne Myers

    POK Flag Weirdness wth binary files

    Wayne Myers, May 26, 2004, in forum: Perl
    Replies:
    1
    Views:
    475
    ! aaa
    May 27, 2004
  2. Replies:
    4
    Views:
    710
    J├╝rgen Exner
    Dec 7, 2004
  3. John Saunders
    Replies:
    4
    Views:
    3,546
    John Saunders
    Aug 29, 2003
  4. steve
    Replies:
    4
    Views:
    533
    Brian van den Broek
    Mar 13, 2005
  5. Guenter Dannoritzer

    #, ## preprocessor operator weirdness with g++

    Guenter Dannoritzer, Nov 24, 2007, in forum: C++
    Replies:
    1
    Views:
    836
    Justin Spahr-Summers
    Nov 24, 2007
Loading...

Share This Page