If you just print an array (as in print @_) there will be nothing to show where each element starts and ends:
$ perl -e '@_ = qw{a bcd ef}; print @_'
abcdef
If you put the array in interpolating quotes,
you will see each element separated by the value of the special variable $"
(which, by default, is a space):
$ perl -e '@_ = qw{a bcd ef}; print "@_"'
a bcd ef
$ perl -e '@_ = qw{a bcd ef}; print qq{@_}'
a bcd ef
In rare situations, perhaps where $" was changed elsewhere in the code,
you may want to make a localised change to $" (typically within an anonymous block).
See local,
"Temporary Values via local()" and
"Localization of special variables"
for more details on that.
Some examples:
$ perl -e '@_ = qw{a bcd ef}; { local $" = " "; print "@_" }'
a bcd ef
$ perl -e '@_ = qw{a bcd ef}; { local $" = "__"; print "@_" }'
a__bcd__ef
$ perl -e '@_ = qw{a bcd ef}; { local $" = "\n"; print "@_" }'
a
bcd
ef
| [reply] [d/l] [select] |
If you just print an array (as in print @_) there will be nothing to show where each element starts and ends
Technically, there will be something: the value of the special variable $, -- it just happens that it defaults to undef (‡) so the separator used is nothing when printed. But if you change or localize its value to a different value, there will be a separator, without having to stringify the array first.
I wouldn't have mentioned this, but you went on to encourage the use of $" and interpolating the array in a string. If all you are doing is trying to get a separator for printing an array or other list (²), then $, will work without having to interpolate/stringify.
-- pryrt
‡: ... and apparently ignores use warnings 'uninitialized';: gotta love magic variables.
²: However, $, applies to everything when printing in list context, so local $,=',';print $a, @_, $b will have more separator instances than local $,=undef; local $"=','; print $a, "@_", $b; -- which may or may not be what you want.
³: Also, $, is much easier to use in a Windows cmd.exe one-liner than $". As a workaround, use English to the rescue:
C:\usr\local\share>perl -MEnglish -wle "@_ = qw{a bcd ef}; print qq(@_
+); local $LIST_SEPARATOR=','; print qq(@_)"
a bcd ef
a,bcd,ef
| [reply] [d/l] [select] |
G'day pryrt,
That must be an extremely sharp, obsidian-bladed, cutting implement that you're using to split such a fine hair.
I applaud your hairdressing skills.
💈 💇 👏
"I wouldn't have mentioned this, ..."
I've no problem with you mentioning special variables, especially the less commonly used ones.
In my opinion, the more exposure they get the better.
"... but you went on to encourage the use of $" and interpolating the array in a string."
I would not say that offering an option that could be used in "rare situations"
qualifies as encouraging such usage.
"If all you are doing is trying to get a separator ... then $, will work without having to interpolate/stringify."
Let's see how that pans out.
The default for $" is ' ' so, except in "rare situations",
there would be no need to localise a new value.
The default for $, is undef so, in most situations, there is a need to localise a new value.
# A simple scenario printing a named array:
$ perl -e 'my @x = qw{a bcd ef}; print "@x\n"'
a bcd ef
$ perl -e 'my @x = qw{a bcd ef}; { local $, = ","; print @x, "\n" }'
a,bcd,ef,
# Oops! Bogus comma at the end. Better split the print list.
$ perl -e 'my @x = qw{a bcd ef}; { local $, = ","; print @x; print "\n
+" }'
a,bcd,ef
# A more complex scenario printing an expression which evaluates to a
+list:
$ perl -e 'print "@{[f()]}\n"; sub f { qw{a bcd ef} }'
a bcd ef
$ perl -e '{ local $, = ","; print f(), "\n"; } sub f { qw{a bcd ef} }
+'
a,bcd,ef,
# Oops! Bogus comma at the end. Better split the print list.
$ perl -e '{ local $, = ","; print f(); print "\n"; } sub f { qw{a bcd
+ ef} }'
a,bcd,ef
Notes:
-
I discovered the "Oops!" while testing the one-liner examples.
I included it because it would appear to be an easily overlooked gotcha.
-
I was using the '@{[...]}' idiom long before I knew it had a name
or that perlsecret even existed.
For those interested, see "perlsecret: Baby cart".
Based on the results above, I will continue to put arrays in interpolating quotes when I print them.
That not a recommendation; just what I'll be doing; everyone is free to make their own choices.
| [reply] [d/l] [select] |
| [reply] [d/l] |
Fair point, Ken, but I was just trying to concisely demonstrate that there was stuff-all in @_ with one bit of code, and the addresses in the other bit, so the 2 bits of code could not be equivalent.
| [reply] |
I thought you were asking why there was no separation of the email addresses in the second and third lines of the output shown.
Seems like I got that wrong: sorry.
I did go back and studied the question more closely.
I note that you've used identical code for both the "prints nothing" and the "prints something":
while (split(/[, ]+/, <DATA>))
{ print @_ }
I suspect the first block should have "print $_", not "print @_".
| [reply] [d/l] [select] |