Evaluates the BLOCK or EXPR for each element of LIST (locally
setting $_ to each element) and returns the list value con
+sisting
of those elements for which the expression evaluated to tr
+ue. In
scalar context, returns the number of times the expression
+ was
true.
So you are making a new list, @primes, from the original list, @numbers, including only those elements of @numbers for which the expression returns true.
Your expression,
{
( exists $is_prime{$_} and $is_prime{$_} )
or
( $is_prime{$_} = is_prime($_) )
}
has two conditions. If either of those returns true for the number from @numbers currently being evaluated, the number is added to @primes.
As grep goes through @numbers, it assigns each one to $_ as it is working with it.
The first condition tests to see whether there is already an entry in the hash %is_prime for the current number:
exists $is_prime{$_}
If there is not, the second part of the first condition, after the and, is ignored and grep() goes on to the second condition. If the number does exist as a key in the hash,
and $is_prime{$_}
checks to see whether additionally the value in the hash is true (ie not 0 or undef).
If that first condition returns true, the second condition is ignored. If the first condition is false, the second condition calls the sub is_prime() with the number:
is_prime($_)
. . . and if the sub returns true, the second condition both adds the number to the hash:
$is_prime{$_} =
# the assigned value is the result of is_prime($_) if that function re
+turned true
. . . and causes the expression to return true, which adds the number to @primes.
Hope this helps.
The way forward always starts with a minimal test.
