My @array will not stop taking in STDIN...
my @array = undef;
while (@array = undef){
@array = <STDIN>;
for (@array[x]=5){
@array = defined;
}
}
On
my @array = undef;
while (@array = undef){
These two lines don't do what (I assume) you think they are doing.
my @array = undef;
This defines an array with a single element which is the special value undef. I suspect that what you actually wanted was:
my @array = ();
which creates an empty array. But Perl arrays are always empty when first created, so this can be simplified to:
my @array;
The second line repeats that error and adds a new one.
while (@array = undef) {
I suspect you want to check for an empty array here and you were reaching for something that meant something like "if @array is undefined). But you missed the fact that in Perl, assignment operators (like =) are different to comparison operators (like ==). So this line assigns undef to @array rather than comparing it. You really wanted @array == undef - but that's not right either.
You need to move away from this idea of checking that an array is "defined". What you're actually interested in is whether an array is empty. And Perl has a clever trick that helps you work that out.
If you use a Perl array in a place where Perl expects to see a single (scalar) value, it gives you the number of elements in the array. So you can write code like:
my $number_of_elements = @an_array;
The boolean logic check in an if or while condition is a single scalar value. So if you want to check if an array contains any elements, you can use code like this:
if (@array) {
# @array contains data
} else {
# @array is empty
}
And to loop while an array contains elements, you can simply write:
while (@array) {
# do something
}
But here, you want to do something while your array is empty. To do that, you can either invert the while condition logic (using ! for "not"):
while (!@array) {
# do something
}
Or you can switch to using an until test (which is the opposite of while):
until (@array) {
# do something
}
I'm going to have to stop there. I hope this gives you some insight into what is wrong with your code. I'm afraid that this level of wrongness permeates the rest of your code too.
As clarified, limit the
STDINto five linesThere are other things to comment on in the posted code. While a good deal of it is cleared up in detail in Dave Cross answer, I'd like to address the business of context when reading from a filehandle.
The "diamond" operator
<>is context-aware. From I/O Operators (perlop)In the usual
whileloop the<>is in the scalar contextand it is the same with
while (<$fh>)since it assigns to$_variable, a scalar, by default.But if we assign to an array, say from a filehandle
$fhwith which a file was openedthen
<>operator works in the list context. It reads all lines until it sees EOF (end-of-file), at which point it returns all lines, which are assigned to@lines. Remember that each line has its newline. You can remove them all bysince chomp works on a list as well.
With
STDINthis raises an issue when input comes from keyboard, as<>waits for more input since EOF isn't coming on its own. It is usually given asCtrl+D† on Unixy systems (Ctrl+Z on Windows).So you can, in principle, have
@array = <STDIN>and quit input withCtrl+Dbut this may be a little awkward for input expected from keyboard, as it mostly implies the need for line by line processing. It is less unusual ifSTDINcomes from a file,or a pipe on the command line
where we do get an EOF (courtesy of EOT).
But I'd still stick to a customary
whilewhen readingSTDIN, and process it line by line.† The
Ctrl+Dis how this is usually referred to but one actually types a low-casedwithCtrl. Note thatCtrlandc(labeled asCtrl+C) does something entirely different; it sends theSIGINTsignal, which terminates the whole program if not caught.