print array with separator?

P

Peng Yu

@array=("a", "b", "c");
print "@array\n";

The above code will not print a separator (say a newline) between the
elements. I could use a foreach loop to do so. But I feel that there
might be a more convenient way. Could somebody let me know if there is
one?

foreach (@array) {
print;
print "\n";
}
 
S

sreservoir

@array=("a", "b", "c");
print "@array\n";

The above code will not print a separator (say a newline) between the
elements. I could use a foreach loop to do so. But I feel that there
might be a more convenient way. Could somebody let me know if there is
one?

foreach (@array) {
print;
print "\n";
}

perldoc -fjoin
 
J

John Bokma

Peng Yu said:
@array=("a", "b", "c");
print "@array\n";

@array = qw( a b c );
$" = "\n";
print "@arr";

$" is the list separator, if you do:

use English;

you can use
$LIST_SEPARATOR = "\n";

which is default a space. (Note that modifying $" or the English variant
stays in effect which might be what you want, or not).

Other options:

print map { "$_\n" } @array;
foreach (@array) {
print;
print "\n";
}

shorter:

for ( @array) {
print "$_\n";
}

or:

print "$_\n" for @array;

or:

print join( "\n", @array ), "\n";

and one I which I don't like much:

map { print "$_\n" } @array;
 
B

Brad Baxter

@array=("a", "b", "c");
print "@array\n";

The above code will not print a separator (say a newline) between the
elements. I could use a foreach loop to do so. But I feel that there
might be a more convenient way. Could somebody let me know if there is
one?

foreach (@array) {
print;
print "\n";
}

The above code positively does printer a separator (a space)
between the elements. Change $" to the separator you want.

use warnings;
use strict;

my @array=("a", "b", "c");
print "@array\n";

$" = "\n";

print "@array\n";
 
J

John Bokma

John W. Krahn said:
Because it *should* be:

print map "$_\n", @array;

Duh, that one is nearly the same as the first one I listed under "other
options" ;-)

As for *should*, I don't like map in void context but that's nowadays
more a matter of taste than anything else as far as I know.

I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
no reason to have a problem with map in void context because we use
other functions in void context without problems (like print).
 
U

Uri Guttman

JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
JB> no reason to have a problem with map in void context because we use
JB> other functions in void context without problems (like print).

the point with map in void context is not efficiency but in conveying
meaning to the reader. map is intended to generate a list, not execute
side effects. for modifier does the same thing and is meant for side
effects as it doesn't generate a list. perl has many related things like
this and you should choose the one with better semantics for your
intentions. map generates lists so use it that way. for modifier doesn't
generate lists so use it for side effects.

uri
 
D

Dr.Ruud

Peng said:
@array=("a", "b", "c");

1. "array" is the stupidest name for an array.
2. whitespace is cheap
0. use strict; use warnings;

my @word = qw/ a b c /;

my @word = "a" .. "c";
 
P

Peter J. Holzer

Peng said:
@array=("a", "b", "c");

1. "array" is the stupidest name for an array. [...]
my @word = qw/ a b c /;

The name of a variable should tell the reader something about its
content and/or purpose. So I would agree that @array is in almost all
cases a very stupid name, as it doesn't tell you anything except that
it's an array, and it does so redundantly ("@" and "array").

However, in this example, the only thing important is that is an array.
It isn't important what kind of data is in the array (except that the
elements are strings or can be stringified) or what the data is used
for. So @array is ok, because it tells you that this is "just an array".

@word, however, is a bad name. It conveys that the array contains
"words". This then causes the reader to wonder what a "word" is (an
English word? No, "b" and "c" are not English words. Some other natural
language? Maybe. Strings matching /^\w+$/? Maybe.) and whether the
example is still valid if an element contains data which is not a
"word".

So @stringifiable_data might be ideal but it's a bit long. @strings is
already a bit too narrow (is 1 a string? Is an object with an
overloaded "" operator a string?), in about the same sense that @array
is too wide. So I don't really see that one of @stringifiable_data,
@strings or @array is clearly better than the others.

hp
 
J

Jürgen Exner

Peter J. Holzer said:
Peng said:
@array=("a", "b", "c");

1. "array" is the stupidest name for an array. [...]
my @word = qw/ a b c /;

The name of a variable should tell the reader something about its
content and/or purpose. So I would agree that @array is in almost all
cases a very stupid name, as it doesn't tell you anything except that
it's an array, and it does so redundantly ("@" and "array").

However, in this example, the only thing important is that is an array.
It isn't important what kind of data is in the array (except that the
elements are strings or can be stringified) or what the data is used
for. So @array is ok, because it tells you that this is "just an array".
Ack

@word, however, is a bad name. It conveys that the array contains
"words".

Actually it conveys that @word contains exactly one word, maybe split
into individual letters.
This then causes the reader to wonder what a "word" is (an
English word? No, "b" and "c" are not English words. Some other natural
language? Maybe. Strings matching /^\w+$/? Maybe.) and whether the
example is still valid if an element contains data which is not a
"word".

If that would have been the intented meaning then @words would have been
preferable to @word.

jue
 
P

Peter J. Holzer

Peter J. Holzer said:
Peng Yu wrote:
@array=("a", "b", "c");

1. "array" is the stupidest name for an array. [...]
my @word = qw/ a b c /;

The name of a variable should tell the reader something about its
content and/or purpose. So I would agree that @array is in almost all
cases a very stupid name, as it doesn't tell you anything except that
it's an array, and it does so redundantly ("@" and "array").

However, in this example, the only thing important is that is an array.
It isn't important what kind of data is in the array (except that the
elements are strings or can be stringified) or what the data is used
for. So @array is ok, because it tells you that this is "just an array".
Ack

@word, however, is a bad name. It conveys that the array contains
"words".

Actually it conveys that @word contains exactly one word, maybe split
into individual letters. [...]
If that would have been the intented meaning then @words would have been
preferable to @word.

I, too, prefer using the plural for array names.

But there are valid arguments for using the singular:

* $word[5] reads more naturally as "word (number) 5" than $words[5].

* In Perl, singular/plural is expressed by the sigil, so
@word is already "several word(s)" and the English plural-s is
at best redundant and at worst harmful, because Perl doesn't
understand it (@words is *not* the array containing $word[0],
$word[1], ...).

So I consider that a matter of personal style and decided not to
complicate this discussion by bringing up the singular/plural debate.
I should have known that somebody else would ...

hp
 
D

Dr.Ruud

Peter said:
Peter J. Holzer said:
Peng Yu wrote:
@array=("a", "b", "c");
1. "array" is the stupidest name for an array.
[...]
my @word = qw/ a b c /;
The name of a variable should tell the reader something about its
content and/or purpose. So I would agree that @array is in almost all
cases a very stupid name, as it doesn't tell you anything except that
it's an array, and it does so redundantly ("@" and "array").

However, in this example, the only thing important is that is an array.
It isn't important what kind of data is in the array (except that the
elements are strings or can be stringified) or what the data is used
for. So @array is ok, because it tells you that this is "just an array". Ack

@word, however, is a bad name. It conveys that the array contains
"words".
Actually it conveys that @word contains exactly one word, maybe split
into individual letters. [...]
If that would have been the intented meaning then @words would have been
preferable to @word.

I, too, prefer using the plural for array names.

But there are valid arguments for using the singular:

* $word[5] reads more naturally as "word (number) 5" than $words[5].

* In Perl, singular/plural is expressed by the sigil, so
@word is already "several word(s)" and the English plural-s is
at best redundant and at worst harmful, because Perl doesn't
understand it (@words is *not* the array containing $word[0],
$word[1], ...).

So I consider that a matter of personal style and decided not to
complicate this discussion by bringing up the singular/plural debate.
I should have known that somebody else would ...

When calling it @word, I hoped for these comments.
:)
 
J

John Bokma

Uri Guttman said:
JB> I wouldn't use it though, but like Abigail, IIRC, once wrote, there is
JB> no reason to have a problem with map in void context because we use
JB> other functions in void context without problems (like print).

the point with map in void context is not efficiency

It used to be, and back then, IMO there was a much stronger argument to
not use map in void context.
but in conveying
meaning to the reader. map is intended to generate a list, not execute
side effects.

But who decides that map is not intended for its side effects? In Perl
there are IMO quite some constructs that are used in somewhat unexpected
ways, especially to people new to the language.
for modifier does the same thing and is meant for side
effects as it doesn't generate a list. perl has many related things like
this and you should choose the one with better semantics for your
intentions. map generates lists so use it that way. for modifier doesn't
generate lists so use it for side effects.

Like I wrote, I don't like it, and won't use it. But the arguments
against using map in void context are more a matter of taste IMO. The
"its not intended for that" is weak at best, in my (current) opinion.
 
D

Dr.Ruud

John said:
the arguments
against using map in void context are more a matter of taste IMO. The
"its not intended for that" is weak at best, in my (current) opinion.

Recent perls do pretty well with map in a void context.

Unrecent perls have real issues with a map inside a map:
memory allocated by the inner map gets released too late.
Nothing to much worry about, unless the inner map is big.
 
J

John Bokma

Dr.Ruud said:
Recent perls do pretty well with map in a void context.

which gives me the impression that it's more a matter of taste/style
than using map "wrong" of for something it is not intented for.

But before the flame war really starts, let me repeat that I don't like
it, and it will be unlikely to show up in my code in the near future.

I've done TE for a book in which the author used a lot map in void
context, and each time I remarked "Don't use void in a map
context". While I don't think it's wrong, I wouldn't recommend it to
use it that often in a book. I haven't seen the final version of the
book yet, so no idea what happened with my advice. But it also made me
think: what's really wrong with it. And I couldn't think of a strong
argument other than that it looks odd (to me). And some of the code
looked better (IMO, again style) with for.
 
J

Jürgen Exner

John Bokma said:
But who decides that map is not intended for its side effects? In Perl
there are IMO quite some constructs that are used in somewhat unexpected
ways, especially to people new to the language.

The root cause of this confusion is probably that for most people with a
formal background in computer science 'map()' is the first operation
that comes to mind when you want to apply an operation to a list of
values. After all it is one of the three canonical higher-order list
functions map, reduce, and filter.

And because Perl happens to have a function map() that happens to work
the same way in a functional as well as in an imperative programming
style it is only natural that people are using it for both purposes.
And I don't see anything wrong with that.

jue
 
J

John Bokma

Tad McClellan said:
Arguments against obfuscation are NOT a matter of taste, they are
a matter of Good Programming Practice.

Like I already wrote several times: I wouldn't use map in void context
at this stage. But I don't think one /must/ (or /should/) not use it in
void context.
Uri's argument was that map in void context conveys the wrong meaning.

One could - to some extent - argue the same for using a 'for' for its
aliasing effect in my opinion, e.g.

my $string = 'hello, world';
for ( $string ) {
s/e/a/;
s/l/1/;
}

I consider the above a Perl idiom; one that I have no problem using.
Yet I am sure it would confuse quite some beginning Perl programmers. To
them it might convey a wrong meaning.

But I don't like to dumb down my Perl code to a beginner's level. YMMV,
in my opinion, it's opinion.

And to avoid of being accused of "promoting map in void context", let me
repeat again: I don't use map in void context, and when TEing a
technical book I recommended the author not to use map in void
context. But it's (no longer) a religious issue to me.
 
U

Uri Guttman

BM> So does delete. Would you object to delete in void context?

but delete conveys the message of doing a side effect. its return value
is nice sugar but isn't needed (amazing how often i show use of delete's
return value and how few know it). map's history (yes, history isn't
taught much) is from building a list from a list. its primary purpose is
building that list and that is what is says to the reader. i always
teach code is for people, not computers. we all can use things in ways
that were unintended but we try to stay away from them for fear of
confusing readers. given that map has the for modifier for use when
doing side effects, that is a better semantic match for that case. note
that for modifier was added after perl5 was first out. map could have
been used for that but given the inefficiency then of throwing out the
list (not true anymore but still) and wrong semantics, it was a good
addition to the language. so why not use it for its purpose? for means
you are doing some side effects in the expression. map means you are
building a list and supposedly not doing side effects.

this is similar to using ?: with side effects. it is a bad idea even if
you get the syntax right (using parens with assignments). ?: is meant to
return a value and not for side effects. perl allows any legit
expression including side effect ones anywhere. that doesn't mean it is
a good idea to do that.

code is for people, not computers.

code is for OTHER people, not yourself.

code is the record of the logical decisions you made when creating this
program.

code is where you can let your ego shine in the reflection of those who
read your code.

uri
 
D

Dr.Ruud

Tad said:
map conveys "I am building a list" (because it returns a list).

IIRC: unless in void context.
(as one of the recent optimizations)

Not that I like to see map used in void context,
I rather see a for loop.


Just joking:

perl -wle '
my @x = -3 .. 3;
grep { ++$_; 0 } @x;
print for @x;
'
-2
-1
0
1
2
3
4


(huh? C<grep ++$_, -3..3> doesn't complain about readonly-ness)
 
S

sreservoir

IIRC: unless in void context.
(as one of the recent optimizations)

not that that really matters.
Not that I like to see map used in void context,
I rather see a for loop.


Just joking:

perl -wle '
my @x = -3 .. 3;
grep { ++$_; 0 } @x;
print for @x;
'
-2
-1
0
1
2
3
4

perl -wle 'my @a = -3 .. 3; map { --$_; () } @a; print for @a'

not much worse, but still hell for readability.
(huh? C<grep ++$_, -3..3> doesn't complain about readonly-ness)

(huh? it's rw pass-by-ref)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top