in reply to Re: Using substr on Hash Keys
in thread Using substr on Hash Keys

I was going to do something like this, but I couldn't reason out which of the delete vs the substr would happen first. It occurred to me, reading your post, that substr doesn't actually modify the string like splice modifies arrays -- so it doesn't matter.

-Paul

Replies are listed 'Best First'.
Re^3: Using substr on Hash Keys
by ikegami (Patriarch) on Sep 10, 2008 at 23:37 UTC

    I was going to do something like this, but I couldn't reason out which of the delete vs the substr would happen first.

    Doesn't matter, unless you expect a collision between a new key and an old key. If that's the case, other solutions have the problem too. (The solution is to use another hash.)

    What does matter is that all the keys are fetched before any insertion into and deletion from the hash. And they are. for loads the entire list over which to iterate into memory before starting to loop.

      I was picturing it like this (incorrectly thinking substring would modify $_), where I think the order does matter, and I can't predict what would happen:
      $hash{ do{ $_ =~ s/(..)$//; $_ } } = delete $hash{ $_ } for keys % +hash;

      What appears to happen is that the lvalue is evaluated first, so I end up deleting the modified key into the new key position (leaving all the old keys in place and defining new keys to undef); but I couldn't have guessed until I tried it, so I'd tend to lean toward a for() loop like my first post.

      And I think that was jwkrahn's point too:

      $hash{ substr $_, 1, 20, "" } = delete $hash{ $_ } for keys %hash;

      -Paul

Re^3: Using substr on Hash Keys
by jwkrahn (Abbot) on Sep 10, 2008 at 21:11 UTC

    Actually, substr can modify the string if you use the fourth argument.

      Yes, but hash keys aren't Perl strings, so keys actually returns a copy of the keys, so substr can only modify the copy, not the key itself.

        I was replying to jettero who said "substr doesn't actually modify the string like splice modifies arrays" and there was no mention of hash keys in his post.

        And actually, hash keys are strings, just not modifiable strings, but there is no error if you try to modify them:

        $ perl -le' use warnings; use strict; my %x = qw/abcd efgh ijkl mnop/; substr $_, 0, 2, "" for %x; print for %x; ' ijkl op abcd gh
Re^3: Using substr on Hash Keys
by pc0019 (Acolyte) on Sep 10, 2008 at 20:28 UTC
    Thanks everyone for the replies. I love the 'TMTOWTDI' factor about Perl, but are both methods as efficient as each other?

      Does it matter? Which do you find more readable? Which are you most likely to use again correctly in the future without looking it up? Which do you think least requires a comment?


      Perl reduces RSI - it saves typing