in reply to Re: Two hash keys created when '.' is in the string
in thread Two hash keys created when '.' is in the string

Oh! Now I feel dumb. See, the second line is there because I need to flag the value as a custom tag, because I am also returning href=, action=, and other 'links'. But I was being really dumb, not realizing that I was creating 2 different keys, one named '$2.cfm' and the other '$2'. <smacks head in disbelief> :)
If you're curious, here's one of my other sections that worked correctly:
while ($_ =~ /(href)[ ="']+(.*?)["'>|\?]/gi) { # finding linked files if (($2 =~ /css/i)|($2 eq $cfm)) { # skipping css files and links t +o self } else { $uniques{"$2"}++; $uniques{$2} = "<norm>"; } }

Replies are listed 'Best First'.
Re^3: Two hash keys created when '.' is in the string
by Eimi Metamorphoumai (Deacon) on Nov 24, 2004 at 18:31 UTC
    I doubt that actually is working. A few problems:
    • You shouldn't ever need to use "$2". It's just the same thing as $2.
    • So you're still assigning two values to the same hash key. The second one overwrites the first, so that $uniques{"$2"}++; line does nothing.
    • Also, | is the bitwise or operator. You want || or or.
    • And finally, running any regexp match overwrites the values of all the number variables (for instance, $2), so after checking $2 =~ /css/i, $2 will be undef.

      "And finally, running any regexp match overwrites the values of all the number variables (for instance, $2), so after checking $2 =~ /css/i, $2 will be undef."

      Not true. Perl doesn't garuntee that it will overright those unless they actualy match. Since that regex isn't doing any captures he should be safe, not that I think its the best way to do it, but its safe.


      ___________
      Eric Hodges

        "Since that regex isn't doing any captures he should be safe" is wrong. Captures or not, $2 is cleared on a successful match.

        $cfm = 'moo'; 'moo' =~ /()(.*)/; if (($2 =~ /css/i) || ($2 eq $cfm)) { print(defined($2)?1:0, $/); # 1, cause match failed $uniques{$2}++; } 'css' =~ /()(.*)/; if (($2 =~ /css/i) || ($2 eq $cfm)) { print(defined($2)?1:0, $/); # 0, cause match succeeded $uniques{$2}++; # $uniques{undef} ??? }
        You're right, it only resets them on a successful match, not on an attempted match. But it will overwrite all of them if there's a successful match, even if the match doesn't include any parens. So if the string /css/ matches, $2 will be undef, and in that case the code won't work right.
      You shouldn't ever need to use "$2". It's just the same thing as $2.
      Not always. Given: sub foo { $^O=~/((.*))/; print for @_ } (a sub that happens to use a regex before accessing its args), foo("$2") if "foobar"=~/(...)(...)/ does something very different from foo($2) if "foobar"=~/(...)(...)/ You should always put magic variables in quotes when passing to a function to prevent this kind of action-at-a-distance.

      Another case where you need to double-quote a variable is when using the string bitwise operators on something that happens to have a cached numeric value:

      $ perl -le'$x = "41"; 0+$x; print for ("$x" ^ "3"), ($x ^ "3")' 1 42
      (Do the noises in my head bother you?)