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

Hey Monks,

I'm attempting to do a one-liner s/replace/ and its not doing what I thought it would. Could someone explain the following for me?
my $page = "page_name.tmpl"; my $mdl = $page =~ s/\.tmpl/\.pl/i;
My thinking was that this would assign the page_name.pl to $mdl, and leave the $page var as page_name.tmpl. But it doesnt...

Cheers.

Replies are listed 'Best First'.
Re: Replace method
by virtualsue (Vicar) on Mar 13, 2006 at 01:01 UTC
    You've received a working answer, now for a little explanation. With the code above, you ended up with $mdl = 1 and $page has its contents clobbered (i.e., changed to "page_name.pl"). Substitution (s///) returns the number of successful matches that occurred, and that's what you (inadvertently) said you wanted.

    If you change the code to (my $mdl = $page) =~ s/\.tmpl$/\.pl/;, then the first thing that happens is that $mdl is set to the value of $page, and because it is the left-hand side of the assignment, $mdl then becomes the target of the =~ binding operation. Note the '$' anchor borisz and I added to the regex - this helps ensure you only change what you intend. What if $page = "my.tmplate.tmpl"?

      Thanks virtualsue, this was an extremely useful explanation and exactly what i was after. If I could double + I would.
      Cheers.
Re: Replace method
by borisz (Canon) on Mar 12, 2006 at 23:26 UTC
    ( my $mdl = $page ) =~ s/\.tmpl$/.pl/i;
    Boris
Re: Replace method
by Fletch (Bishop) on Mar 13, 2006 at 00:11 UTC

    B::Deparse can be your friend when things aren't causing syntax errors but don't behave the way you expect. You may find that Perl's not understanding things the same way you intended.

    gamera:~ 602> perl -MO=Deparse,-p,-q <<'EOT' heredoc> my $page = "page_name.tmpl"; heredoc> my $mdl = $page =~ s/\.tmpl/\.pl/i; heredoc> EOT (my $page = 'page_name.tmpl'); (my $mdl = ($page =~ s/\.tmpl/.pl/i)); - syntax OK