talexb has asked for the wisdom of the Perl Monks concerning the following question:

This is frustrating but I can't figure out why it isn't working. I want to replace $1 (the full file name) with whatever the root file name ($2) maps to, based on information stored in a hash. If the mapping doesn't exist, I want to display that result instead.

s/$1/exists($hash{$2}) ? $hash{$2} : "$2:mapping not done"/e;
So why do I get
Use of uninitialized value in concatenation (.) or string
I expected instead for the !defined condition to trigger the 'mapping not done' string.

The variable %hash is currently empty. I plan to populate it as I go through the files.

Hand is open and facing forehead, ready to move ..

--t. alex
Life is short: get busy!

Replies are listed 'Best First'.
Re: Using 'e' in s///
by chromatic (Archbishop) on Aug 13, 2003 at 20:50 UTC

    Where do you capture $2? If it's from a previous regex, it won't be available after a successful match that resets the capture variables!

    That one bites me too occasionally, which is how I remember.

      D'Oh! (sound of hand slapping forehead repeatedly) Thank you.

      --t. alex
      Life is short: get busy!
Re: Using 'e' in s///
by hardburn (Abbot) on Aug 13, 2003 at 20:51 UTC

    My guess is that when you do the first portion of the subtitiution, Perl looks for any capturing matches and fills in $1, $2, etc. as needed. Since there aren't any captures, the values of the capturing vars are undef by the time it gets to the second part of the substitution.

    To get around this, save the value of $2 before you do your substitution.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Using 'e' in s///
by Aristotle (Chancellor) on Aug 14, 2003 at 00:57 UTC
    s/$1/ .... /;
    You cannot modify the match variables, anyway. You need a different approach.
    Err, oh dear.

    Makeshifts last the longest.

      You cannot modify the match variables, anyway.

      That's not an attempt to modify $1 at all. It's an attempt to use it as a pattern, which is fine.

      $ perl -le '$_="foo"; /(o)/; s/$1/x/; print' fxo
      You seem to have confused that with $1 =~ s/.../.../;

      -sauoq
      "My two cents aren't worth a dime.";