J
John E. Jardine
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|$fltr_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";
}
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";
"$fltr_attr1|$fltr_op1|$fltr_val1|$fltr_attr2|$fltr_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";
}