I came across a function today that made me stop and think. I can't think of a good reason to do it:
sub replace_string {
my $string = shift;
my $regex = shift;
my $replace = shift;
$string =~ s/$regex/$replace/gi;
return $string;
}
The only possible value I can see to this is that it gives you the ability to control the default options used with a substitution, but I don't consider that useful. My first reaction upon seeing this function get called is "what does this do?". Once I learn what it does, I am going to assume it does that from that point on. Which means if it changes, it will break any of my code that needs it to do that. This means the function will likely never change, or changing it will break lots of code.
Right now I want to track down the original programmer and beat some sense into him or her. Is this a valid desire, or am I missing some value th开发者_C百科is function brings to the table?
The problems with that function include:
- Opaque:
replace_string
doesn't tell you that you're doing a case-insensitive, global replace without escaping. - Non-idiomatic:
$string =~ s{$this}{$that}gi
is something you can learn what it means once, and its not like its some weird corner feature.replace_string
everyone has to learn the details of, and its going to be different for everyone who writes it. - Inflexible: Want a non-global search-and-replace? Sorry. You can put in some modifiers by passing in a
qr//
but that's far more advanced knowledge than thes///
its hiding. - Insecure: A user might think that the function takes a string, not a regex. If they put in unchecked user input they are opening up a potential security hole.
- Slower: Just to add the final insult.
The advantages are:
- Literate: The function name explains what it does without having to examine the details of the regular expression (but it gives an incomplete explanation).
- Defaults: The
g
andi
defaults are always there (but that's non-obvious from the name). - Simpler Syntax: Don't have to worry about the delimiters (not that
s{}{}
is difficult). - Protection From Global Side Effects: Regex matches set a salad of global variables (
$1
,$+
, etc...) but they're automatically locally scoped to the function. They won't interfere if you're making use of them for another regex.
A little overzealous with the encapsulation.
print replace_string("some/path", "/", ":");
Yes, you get some magic in not having to replace / with a different delimiter or escape / in the regex.
If it's just a verbose replacement for s///
then I'd guess that it was written by someone who came to Perl from a language where using regular expressions required extra syntax and who is/was more comfortable coding that way. If that's the case I'd classify it as Perl baby-talk: silly and awkward to seasoned coders but not bad -- not bad enough to warrant a beating, anyway. ;)
If I squint really hard I can almost see cases where such a function might be useful: applying a bunch of patterns to a bunch of strings, allowing user input for the terms, supplying a CODE reference for a callback...
My first reaction upon seeing that is a new Perl programmer didn't want to remember the syntax for a regular expression and created a function he or she could easily remember, without learning the syntax.
The only reason I can see other than the ones mentioned already ( new programmer does not want to remember regex syntax ) is that it is possible they may be using some IDE that does not have any syntax highlighting for regex, but it does exist for functions they've written. Not the best of reasons, but plausible.
精彩评论