Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > s/// has apparent side effect on grep()

Reply
Thread Tools

s/// has apparent side effect on grep()

 
 
John E. Jardine
Guest
Posts: n/a
 
      04-12-2004
Hi,

Problem:
Executing 's///' has a side effect on grep null string matching.
If line 62, the substitution, is executed the last two values returned by
grep and printed on lines 68, 69 are different than the values returned and
printed when line 62 is commented out. Line 62 shouldn't have any impact on
lines 67,68 & 69.

Environment:
(1) Reproducable under Perl 5.6.1 running on Linux 2.4.5 (Slackware 8.0
installation) Pentium MMX/166MHz, 96MB Ram.
(2) Reproducable under Perl 5.8.0 running on Linux 2.6.5 (Slackware 9.1.0
installation) AMD Athlon 64 3000+, 1GB Ram

To reply by e-mail, remove the dot-baseball treat-dot from my e-mail address

Example Code:
#!/usr/bin/perl -w
my $item;
my $fltr_expr;
my $fltr_attr1;
my $fltr_op1;
my $fltr_val1;
my $fltr_attr2;
my $fltr_op2;
my $fltr_val2;
my $fltr_attr3;
my $fltr_op3;
my $fltr_val3;
my @test_data = ();
my %fltr_num_ops;
my %fltr_str_ops;
my %card_columns = (network => "network_srname",
node => "node_srname",
nodetype => "node_srtype",
area => "node_lata",
cardtype => "srcardtype");


$fltr_num_ops{EQUAL} = " == ";
$fltr_num_ops{NOTEQUAL} = " != ";
$fltr_num_ops{LIKE} = " =~ m// ";
$fltr_num_ops{NOTLIKE} = " !~ m// ";
$fltr_str_ops{EQUAL} = " eq ";
$fltr_str_ops{NOTEQUAL} = " ne ";
$fltr_str_ops{LIKE} = " =~ m// ";
$fltr_str_ops{NOTLIKE} = " !~ m// ";

#------------------------------------------------------------------------
# Test data normally retrieved from database. This accurately represents
# the problem though.
#------------------------------------------------------------------------
push(@test_data, "cardtype|LIKE|HUB|||||||");
push(@test_data, "cardtype|EQUAL|CC2|||||||");
foreach $item (@test_data) {
( $fltr_attr1, $fltr_op1, $fltr_val1, $fltr_attr2, $fltr_op2, $fltr_val2,
$fltr_attr3, $fltr_op3, $fltr_val3 ) = split(/\|/, $item);

$fltr_attr1 =~ tr/A-Z/a-z/;
$fltr_attr1 =~ s#^\s*(\S*)\s*$#$1#;
$fltr_op1 =~ s#^\s*(\S*)\s*$#$1#;
$fltr_val1 =~ s#^\s*(\S*)\s*$#$1#;

#---------------------------------------------------------------------
# $fltr_attr2, $fltr_op2, fltr_val2, $fltr_attr3, $fltr_op3, fltr_val3
# are not processed in this example - normally they would've been.
#---------------------------------------------------------------------
$fltr_expr = "";
if( $fltr_val1 =~ m#^\d+$# ) {
$fltr_expr = qq{$fltr_attr1 $fltr_num_ops{$fltr_op1} $fltr_val1}; }
else {
$fltr_expr = qq{$fltr_attr1 $fltr_str_ops{$fltr_op1} "$fltr_val1"}; }

#---------------------------------------------------------------------
# This is where the problem is. Try (un)commenting out the
# middle line (substitution). It changes the results of the grep()s
# in the next section.
#---------------------------------------------------------------------
print "Before Substitute: '$fltr_expr'\n";
# $fltr_expr =~ s#m// +"*([^"]+)"*#m/$1/#g;
print "After Substitute: '$fltr_expr'\n";

print
"$fltr_attr1|$fltr_op1|$fltr_val1|$fltr_attr2|$flt r_op2|$fltr_val2|$fltr_att
r3|$fltr_op3|$fltr_val3\n";

print sprintf("grep(/$fltr_attr1/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr1/, keys %card_columns)));
print sprintf("grep(/$fltr_attr2/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr2/, keys %card_columns)));
print sprintf("grep(/$fltr_attr3/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr3/, keys %card_columns)));
print "fltr_attr1 = '$fltr_attr1'\n";
print "fltr_op1 = '$fltr_op1'\n";
print "fltr_val1 = '$fltr_val1'\n";
print "fltr_attr2 = '$fltr_attr2'\n";
print "fltr_op2 = '$fltr_op2'\n";
print "fltr_val2 = '$fltr_val2'\n";
print "fltr_attr3 = '$fltr_attr3'\n";
print "fltr_op3 = '$fltr_op3'\n";
print "fltr_val3 = '$fltr_val3'\n";
foreach (keys %card_columns) {
print "'$_' = '$card_columns{$_}'\n"; }
print "\n";
}


 
Reply With Quote
 
 
 
 
Joe Smith
Guest
Posts: n/a
 
      04-12-2004
John E. Jardine wrote:

> Executing 's///' has a side effect on grep null string matching.


That is correct. It is documented behavior.

If the PATTERN evaluates to the empty string, the last success-
fully matched regular expression is used instead.

You need to change lines 67-69 in your program to

printf("grep(/$fltr_attr1/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr1/, keys %card_columns))) if $fltr_addr1 ne "";
printf("grep(/$fltr_attr2/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr2/, keys %card_columns))) if $fltr_addr2 ne "";
printf("grep(/$fltr_attr3/, keys %%card_columns) = %d\n",
scalar(grep(/$fltr_attr3/, keys %card_columns))) if $fltr_addr3 ne "";

-Joe
 
Reply With Quote
 
 
 
 
John Jardine
Guest
Posts: n/a
 
      04-13-2004
Hi Joe,

My bad - I must have missed that and simply never hit the issue before.
Thanks for clearing it up for me.

Cheers,
J.J.

On Mon, 12 Apr 2004, Joe Smith wrote:

>John E. Jardine wrote:
>
>> Executing 's///' has a side effect on grep null string matching.

>
>That is correct. It is documented behavior.
>
> If the PATTERN evaluates to the empty string, the last success-
> fully matched regular expression is used instead.
>
>You need to change lines 67-69 in your program to
>
>printf("grep(/$fltr_attr1/, keys %%card_columns) = %d\n",
>scalar(grep(/$fltr_attr1/, keys %card_columns))) if $fltr_addr1 ne "";
>printf("grep(/$fltr_attr2/, keys %%card_columns) = %d\n",
>scalar(grep(/$fltr_attr2/, keys %card_columns))) if $fltr_addr2 ne "";
>printf("grep(/$fltr_attr3/, keys %%card_columns) = %d\n",
>scalar(grep(/$fltr_attr3/, keys %card_columns))) if $fltr_addr3 ne "";
>
> -Joe
>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Apparent Java Location Restriction kvnsmnsn@hotmail.com Java 2 06-17-2005 05:23 PM
Session - Screen Switches for no apparent reason. ASP .Net 4 01-28-2005 01:03 AM
Has apparent 2.4b1 bug been fixed? flatten in Lib\compiler\ast.py overloads 'list' name Bengt Richter Python 3 01-19-2005 05:17 PM
Apparent session crosstalk Shari ASP .Net 3 10-01-2004 05:07 PM
Interface Hangs with no Apparent Reason Bitoy Cisco 3 06-08-2004 11:25 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57