Suppose that you’ve got a long filename like
/usr/local/bin/perl in your program, and you need to determine the basename. That’s easy enough since the basename is everything after the last slash (in this case,
my $name = "/usr/local/bin/perl"; (my $basename = $name) =~ s#.*/##; # Oops!
As you saw earlier, first Perl does the assignment inside the parentheses, and then it does the substitution. The substitution is supposed to replace any string ending with a slash (that is, the directory name portion) with an empty string, leaving the basename.
If you try this, it will seem to work. Well, it will seem to, but there are three problems.
First, a Unix file or directory name could contain a newline character. (It’s not something that’s likely to happen by accident, but it’s permitted.) Since the regular expression dot (
.) can’t match a newline, a filename like the string "
/home/fred/flintstone\n/brontosaurus" won’t work right because that code will think the basename is "
flintstone\n/brontosaurus“. You could fix that with the
/s option to the pattern (if you remembered about this subtle and infrequent case), making the substitution look like this:
s#.*/##s. The second problem is this is Unix-specific. It assumes the forward slash will be the directory separator as it is on Unix and not the backslash or colon that some systems use.
The third (and biggest) problem with this is we’re trying to solve a problem someone else has solved. Perl comes with a number of ...