I have been programming in Perl, off and on, for years now, although only sporadically is it my primary language. Because I often go months without writing any perl, I rely heavily on my dog-eared Camel Book to remind me how to do things. However, when I copy recipes verbatim with no understanding, this bothers me. This is one of the most vexing: On page 154 of the 3rd edition Camel, there is an example for "modifying strings en passant, which reads like this:
($lotr = $hobbit) =~ s/Bilbo/Frodo/g;
Q1) what is going on here? On what, exactly, is the regex operating?
Q2) Is this near-magical syntax necessary for such a basic operation as "take a string from $a, modify it with a regex, place result in $b"?
Q3) How do I do this operation using the loop default variable as the initial string?
Apologies in advance to Perl dreamers for whom the above looks perfectly natural.
A Perl operator is a series of one or more symbols used as part of the syntax of a language. Each operator operates on zero or more operands. Think of an operator as a special sort of function the parser understands and its operands as arguments. You've seen how Perl manages context through its operators.
The most commonly used special variable is $_, which contains the default input and pattern-searching string. For example, in the following lines − #!/usr/bin/perl foreach ('hickory','dickory','doc') { print $_; print "\n"; }
Performing a regex search-and-replace is just as easy: $string =~ s/regex/replacement/g; I added a “g” after the last forward slash. The “g” stands for “global”, which tells Perl to replace all matches, and not just the first one.
Hmmm... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g
is one of the many magicks of Perl. Now for some answers.
Q1) $lotr
is being assigned the value contained in $hobbit
. After the assignment, we can forget about the source variable. Treat ($lotr = $hobbit)
as it's own statement as-if we had written:
$lotr = $hobbit;
$lotr =~ s/Bilbo/Frodo/g;
instead. The regex is operating on $lotr
.
Q2) The syntax is simply a one-line version of the snippet given above. Think of it as "copy the string from $a
, copy it into $b
, and modify $b
with the regex" instead of "take a string from $a
, modify it with a regex, place result in $b
"
Q3) I'm assuming that you mean the default pattern searching space by "loop default variable"? In that case, just use $_
instead of $hobbit
:
while (<>) {
chomp;
($lotr = $_) =~ s/Bilbo/Frodo/g;
print "\$lotr = [$lotr]\n";
print "\$_ = [$_]\n";
}
Interestingly enough, the magic var $_
is not modified by this operation. This is how you can conclude that the assignment happens before the regex substitution and that the substitution does not interact on the default pattern space in any way.
And for the experienced Perl programmers thing... I don't know too many people that are thrown by some piece of Perl syntax regardless of how long they have been staring at it 'cept Mr. Schwartz of course ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With