if,then with array containing scalars

E

erik

I want to check all these scalars for the value of OK in them. The code
below does not works. Maybe I should do a foreach with $line but that
is not working either. How can I check the re OK on each element in the
array?

(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)
{
print "<body><font color=33CC33>YOU CAN CUTOVER THIS DEVICE TO
OPERATIONS</font></body>";
}
else{
print "<body><font color=FF0000>NOT OK TO CUTOVER, PLEASE FIX AND
RETEST</font></body>";
}
 
G

Gunnar Hjalmarsson

erik said:
I want to check all these scalars for the value of OK in them. The code
below does not works.

And since you have warnings enabled, you already know one of the reasons
why, right?
Maybe I should do a foreach with $line but that
is not working either.

Why not? Did you really try hard enough?
How can I check the re OK on each element in the
array?

(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)

This is one possibility:

if ( ( grep $_ eq 'OK', @final_report ) == @final_report )

See "perldoc -f grep".
 
J

Jürgen Exner

erik said:
I want to check all these scalars for the value of OK in them. The
code below does not works. Maybe I should do a foreach with $line but
that is not working either. How can I check the re OK on each element
in the array?

(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)

Well, let's see what the documentation has to say about this construct.
"perldoc perlop" about the binding operator:
Binary "=~" binds a scalar expression to a pattern match.[...]
Well, why did you think =~ would work on an array?

Did you consider to simply grep() for your OK elements (or non-OK) elements
and just count the returned items?
If zero non-OK items, then everything must be OK, right?

jue
 
S

Sherm Pendley

erik said:
I want to check all these scalars for the value of OK in them. The code
below does not works. Maybe I should do a foreach with $line but that
is not working either. How can I check the re OK on each element in the
array?

(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)

You've misunderstood what a match does in list context, like you're using it
here. What it *doesn't* do is match against all the list elements - you've
already figured out that part! :)

What it *does* do is return a list of matched subexpressions. But the regex
you're matching against above doesn't have any subexpressions. So the
returned list is empty.

For details, have a look at:
perldoc perlre
perldoc perlretut

If what you want to do is perform a given match against each item in a list,
you want to use the grep() function, like this:

if (grep(/OK/, @final_report)) {
# ... do stuff
}

For details, have a look at:
perldoc -f grep

sherm--
 
S

Sherm Pendley

robin said:
the problem is that =~ does not do much with arrays.

A match in list context returns a list of matched values - that's a far cry
from "not much". It's quite useful, in fact, in helping to produce more
compact, readable code.

Here's an example from 'perlretut', first using a match in scalar context:

# Extract hours, minutes, seconds
$_ = '10:15:30';
my ($hours, $minutes, $seconds);
if (/(\d\d):(\d\d):(\d\d)/) {
$hours = $1;
$minutes = $2;
$seconds = $3;
}

Now, here's the same code, using an array:

$_ = '10:15:30';
my ($hours, $minutes, $seconds) =~ /(\d\d):(\d\d):(\d\d)/;

For details, have a look at:
perldoc perlretut

The whole thing is a good read, but the section titled "Extracting matches"
is particularly relevant to this particular subject.

sherm--
 
C

Chris Mattern

erik said:
I want to check all these scalars for the value of OK in them. The code
below does not works. Maybe I should do a foreach with $line but that
is not working either. How can I check the re OK on each element in the
array?

perldoc -f grep
(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)

This uses @final_report in a scalar context. You are asking if
the number "3" contains the string "OK".
{
print "<body><font color=33CC33>YOU CAN CUTOVER THIS DEVICE TO
OPERATIONS</font></body>";
}
else{
print "<body><font color=FF0000>NOT OK TO CUTOVER, PLEASE FIX AND
RETEST</font></body>";
}

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
S

Sherm Pendley

Sherm said:
If what you want to do is perform a given match against each item in a
list, you want to use the grep() function, like this:

if (grep(/OK/, @final_report)) {

D'oh! grep() returns the number of matched elements, so obviously you want
to compare that to the number of elements in @final_report:

if(grep(/OK/, @final_report) == @final_report) {

sherm--
 
J

Jürgen Exner

Gunnar said:
And since you have warnings enabled, you already know one of the
reasons why, right?


Why not? Did you really try hard enough?


This is one possibility:

if ( ( grep $_ eq 'OK', @final_report ) == @final_report )

Close, but the OP explicitely asked for an RE match of 'OK' on each element,
not for equality to 'OK'.
However, because 'OK' doesn't contain any regular expression a simple
index() should work. No need to deploy the big RE gun.

jue
 
B

Bob Walton

erik said:
I want to check all these scalars for the value of OK in them. The code
below does not works. Maybe I should do a foreach with $line but that
is not working either. How can I check the re OK on each element in the
array?

(this code does not work)
@final_report = ($log_action,$crc_action,$voyence_action);
if (@final_report =~ /OK/)

The =~ operator accepts a scalar left-hand-side, so in this case,
it will be equivalent to:

if ('3' =~ /OK/)

as the scalar value of @final_report is the number of elements in
the array. Which won't match. You'll need to check each array
element for a match, then decide what action to take based on how
many array elements matched. See below for an example.
{
print "<body><font color=33CC33>YOU CAN CUTOVER THIS DEVICE TO
OPERATIONS</font></body>";
}
else{
print "<body><font color=FF0000>NOT OK TO CUTOVER, PLEASE FIX AND
RETEST</font></body>";
}

Here is maybe what you meant:

use warnings;
use strict;
#change one or more of following 3 lines to something
#not containing OK for testing
my $log_action='OK';
my $crc_action='OK';
my $voyence_action='OK';
my @final_report = ($log_action,$crc_action,$voyence_action);
my $OKcount=0;
for (@final_report){
$OKcount++ if /OK/;
}
if ($OKcount>=@final_report){ #assumes all must be OK
print "<body><font color=33CC33>YOU CAN CUTOVER THIS DEVICE
TO OPERATIONS</font></body>";
}
else{
print "<body><font color=FF0000>NOT OK TO CUTOVER, PLEASE FIX
AND RETEST</font></body>";
}

....
 
J

Jürgen Exner

Sherm said:
A match in list context returns a list of matched values

True.
But the return value of the m operator has little to do with the left
argument of the binding operator.

jue
 
G

Gunnar Hjalmarsson

Sherm said:
A match in list context returns a list of matched values - that's a far cry
from "not much".

I'd give robin more right this time. See my comments on your other post
in this thread.
Here's an example from 'perlretut', first using a match in scalar context:

# Extract hours, minutes, seconds
$_ = '10:15:30';
my ($hours, $minutes, $seconds);
if (/(\d\d):(\d\d):(\d\d)/) {
$hours = $1;
$minutes = $2;
$seconds = $3;
}

Now, here's the same code, using an array:

$_ = '10:15:30';
my ($hours, $minutes, $seconds) =~ /(\d\d):(\d\d):(\d\d)/;

my ($hours, $minutes, $seconds) = /(\d\d):(\d\d):(\d\d)/;
 
G

Gunnar Hjalmarsson

Jürgen Exner said:
Close, but the OP explicitely asked for an RE match of 'OK' on each element,
not for equality to 'OK'.

Well, he said "check ... for the value of 'OK'". It's true that he used
the m// operator, but people often do so also when it's not necessary. I
simply made an assumption.
However, because 'OK' doesn't contain any regular expression a simple
index() should work. No need to deploy the big RE gun.

We seem to be agreed on the latter, at least. :)
 
S

Sherm Pendley

Gunnar said:
No, no. I'm afraid that also you have misunderstood what it does.

Not so much a misunderstanding as a late-night, half-asleep brain freeze.
One of those things where you look back the next day, with a clear head,
and think "WTF was I thinking? I know better than that..."

I'd better get some sleep, before I start making idiotic comparisons between
Python and Perl.

sherm--
 
G

Gunnar Hjalmarsson

Sherm said:
I'd better get some sleep, before I start making idiotic comparisons between
Python and Perl.

On behalf of all sane readers of this group: Thanks!! :)
 
G

Gunnar Hjalmarsson

Tad said:
False!

The pattern match above is in *scalar* context.

Thanks for correcting my attempt at a correction. :-/

Sometimes I wish you could just delete a thread and start it all over.
 

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,754
Messages
2,569,522
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top