$, the output field separator, and $" the list separator of Perl
Perl has a number of "magic" variables. Some are really useful, some are there mostly for historical reasons. This time we are going to look at two: $, also known as output field separator, and $" also known as list separator.
Assuming this at the beginning of our file:
#!/usr/bin/perl use strict; use warnings; use 5.010; my @names = qw(Foo Bar Que);
$, the Output field separator
When printing a list of values or an array, Perl automatically prints the content of $,, which is undef by default, between every two values.
So say 'A', 'B', 'C'; will print ABC
and say @names; will print FooBarQue
One can change $, to any string
$, = '--'; say 'A', 'B', 'C'; # A--B--C say @names; # Foo--Bar--Que
but it is really not advised! Especially because $, is global to
the whole process so if we change it in one location, it changes to the
rest of the code. Even in other modules. (Unless we localize it using
the local statement.)
Using join is much clearer and has the same result:
In really serious cases, I'd probably create a function, rather than change $,:
It is much more readable.
The way to remember the variable is that it "replaces commas in a print statement".
If using the English module, $, is also
called $OUTPUT_FIELD_SEPARATOR or $OFS.
Similarly, when we embed an array in a double-quoted string, the expression will return
the values of the array separated by the content of $", which by default is a single space.
say "@names"; will print Foo Bar Que.
Here too we can change the content of $":
or we could use join instead:
or create a function:
When using the English module, the variable $" is also called $LIST_SEPARATOR.
But, let me repeat, I would not recommend changing it.
So if I don't recommend using it, how can I make sure neither my code, nor the code of my fellow co-workers
change this variable?
Perl::Critic has a policy called
Variables::ProhibitPunctuationVars
that will catch the use of these variables in your code. You can try to find them using
perlcritic --single-policy Variables::ProhibitPunctuationVars script.pl that will give you a report like this:
Magic punctuation variable $, used at line 9, column 1. See page 79 of PBP. (Severity: 2)
You could also set up an automated test using Test::Perl::Critic.
See how you could improve your code using Perl::Critic one policy at a time.
While I still not recommend you to change the variables, but if you really have to, or you find a piece of code that does it and you
want to make sure the change does not have a global impact you can localize the change:
say join '--', 'A', 'B', 'C';
say join '--', @names;
sub mysay {
say join '--', @_,
}
mysay 'A', 'B', 'C';
mysay @names;
$" the list separator
$" = '-+-';
say "@names"; # Foo-+-Bar-+-Que
say join '-+-', @names; # Foo-+-Bar-+-Que
sub mysay {
say join '-+-', @_,
}
mysay @names; # Foo-+-Bar-+-Que
Finding the violators using Perl::Critic
Localizing $" and $,
say "@names"; # Foo Bar Que
{
local $" = '-+-'; # Foo-+-Bar-+-Que
say "@names";
}
say "@names"; # Foo Bar Que
Published on 2014-02-13