minor re, problelm

G

George

I have
($pI,$vI)=($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/);
print "($pI,$vI)";
which work fine if $input="24,qwerr" but returns (1,) if $input="38,29"
why is that
why this "or" is not working, and how can I use ?: in this case
 
A

A. Sinan Unur

@news.europe.nokia.com:

Putting some effort into writing your question will usually help you
find the answer in the process.

Please do read the posting guidelines posted here regularly.
I have
($pI,$vI)=($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/);
print "($pI,$vI)";
which work fine if $input="24,qwerr" but returns (1,) if
$input="38,29"

Please define what "work fine" means?
why is that
why this "or" is not working,

I do not see any "or" in the code you posted.

As always, the Perl documentation is your friend. From perldoc perlop:

In particular, this means that you shouldn't use this for selecting
between two aggregates for assignment:

@a = @b || @c; # this is wrong
@a = scalar(@b) || @c; # really meant this
@a = @b ? @b : @c; # this works fine, though


Which leads us to:

#! /usr/bin/perl

use strict;
use warnings;

print "@{[ print_matches('24,qwerr') ]}\n";
print "@{[ print_matches('38,29') ]}\n";

sub print_matches {
my ($input) = @_;
my @ret = ($input =~ /(\d+),(\d+)/)
? ($1, $2)
: ($input =~ /(.*),(.*)/);
}

__END__

D:\Home\asu1\UseNet\clpmisc> v
24 qwerr
38 29

Sinan
 
A

A. Sinan Unur

sub print_matches {
my ($input) = @_;
my @ret = ($input =~ /(\d+),(\d+)/)
? ($1, $2)
: ($input =~ /(.*),(.*)/);
}

__END__

Of course, it would be better to call this sub something other than
print_matches because one thing it does not do is print.

Sinan.
 
A

Anno Siegel

George said:
I have
($pI,$vI)=($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/);
print "($pI,$vI)";
which work fine if $input="24,qwerr" but returns (1,) if $input="38,29"
why is that
why this "or" is not working, and how can I use ?: in this case

Do you have strict and warnings on? It doesn't look like it. You
should.

Precedence, context, and a peculiar behavior of "||" work together to
bring about this result. First off, "||" has higher precedence than
"=", so the expression is evaluated as

($pI,$vI)= ( ($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/) );

Now, in perldoc perlop we find

Binary "||" performs a short-circuit logical OR operation.
That is, if the left operand is true, the right operand is
not even evaluated. Scalar or list context propagates
down to the right operand if it is evaluated.

The peculiarity is in the last sentence.

The left operand is evaluated in boolean context, so the first regex
will return true or false, but not the list of captures. If the first
regex matches, that's it, so $pI is set to 1 and $vI remains undefined.
If it doesn't match, the second regex is evaluated in list context and
returns the two captures.

To make it work right, rewrite it as

($pI, $vI) = ( $input =~ /(\d+),(\d+)/) or
($pI, $vI) = ( $input =~ /(.*),(.*)/);


Note the use of the low-precedence "or" instead of "||".

Anno
 
G

George

Anno said:
Do you have strict and warnings on? It doesn't look like it. You
should.

Precedence, context, and a peculiar behavior of "||" work together to
bring about this result. First off, "||" has higher precedence than
"=", so the expression is evaluated as

($pI,$vI)= ( ($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/) );

Now, in perldoc perlop we find

Binary "||" performs a short-circuit logical OR operation.
That is, if the left operand is true, the right operand is
not even evaluated. Scalar or list context propagates
down to the right operand if it is evaluated.

The peculiarity is in the last sentence.

The left operand is evaluated in boolean context, so the first regex
will return true or false, but not the list of captures. If the first
regex matches, that's it, so $pI is set to 1 and $vI remains
undefined. If it doesn't match, the second regex is evaluated in
list context and returns the two captures.

To make it work right, rewrite it as

($pI, $vI) = ( $input =~ /(\d+),(\d+)/) or
($pI, $vI) = ( $input =~ /(.*),(.*)/);


Note the use of the low-precedence "or" instead of "||".

Anno

thank you for taking out time and explaning it
 

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,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top