views:

113

answers:

3

I've got a piece of code that works fine. It basically loops through each element of a hash using foreach() and applies a transformation to it using a regular expression, like so :

foreach my $key ( keys( %{$results} ) ) {
   $results->{$key}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi;
}

$results is a hashref returnd by DBI's fetchall_hashref() function.

Just out of curiosity, I wanted to see if I could rewrite it using map() instead, as shown below :

map {
   $results{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

Unfortunately, that doesn't work. I've tried all sorts of things but so far without success. Anybody knows how to do this? Thanks.

UPDATE

The corrected code, as answered by ysth:

map {
   $results->{$_}{uri} =~ s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

and the improved version with less leaning toothpicks suggested by Sinan Ünür

map {
   $results->{$_}{uri} =~ s{".*/(.*\.*(gif|jpe?g|png))"}{/resources/uploads/$1}gi
} keys %{$results};
+5  A: 

The second piece of code uses a hash but the first one uses a hash reference. The following seems to work:

use warnings;
use strict;

my $results = {
    a => {uri => "\"c/x.png\"" },
    b => {uri => "\"d/y.jpeg\""}
};

map {
   $results->{$_}{uri} =~ 
       s/\".*\/(.*\.*(gif|jpe?g|png))\"/\/resources\/uploads\/$1/gi
} keys %{$results};

for my $k (keys %$results) {
    print "$k $results->{$k}{uri}\n";
}
Kinopiko
+8  A: 

In the map version, you've mistakenly changed $results->{ to $results{. Put the -> back in and it should work.

ysth
Ah, you're right! All bugs are indeed shallow with enough Stackoverflow eyeballs. ;-) Thanks.
GeneQ
+10  A: 

It's worth mentioning that you could get away with

$_->{uri} =~ s/foo/bar/ for values %$results;

in this case. Poking around in the data structure doesn't disturb the references that make it up.

hobbs
Cool. Once again this proves that there's always more than one (surprising) way to do things in Perl. :-)
GeneQ