On Thu Sep 07 18:11:43 2017, fgssfgs wrote:
Show quoted text> After this call, warnings are left disabled:
>
> my $xml = XML::Smart->new(q`<?xml version="1.0" encoding="iso-8859-1" ?>
> <root>
> <foo arg="abc">ABC</foo>
> <foo arg="xyz">XYZ</foo>
> </root>
> `);
>
> warn "About to foo";
> my $foo = $xml->{root}{foo}('arg', 'eq', 'xyz');
> warn "This doesn't get warned";
I have this same bug. I am running version 1.77 of XML::Smart. I've looked at the latest version, 1.79, and the bug is there too.
The bug is in the find_args() method in XML::Smart.
############
# FIND_ARG #
############
sub find_arg {
my $this = shift ;
...[snip]...
foreach my $search_i ( @search ) {
my ($name , $type , $value) = @{$search_i} ;
$type =~ s/\s//gs ;
$i++ ;
my $hash ;
if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;}
else { $hash = $hash_i ;}
my $data ;
if ($name =~ /^content$/i) { $name = 'CONTENT' ;}
$data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ;
$data = $$data{CONTENT} if ref($data) eq 'HASH' ;
_unset_sig_warn() ;
if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;}
_reset_sig_warn() ;
}
You can see the call to _unset_sig_warn() just before the bunch of if tests: if none of the tests succeeds _reset_sig_warn() is called to restore the previous sig_warn behaviour. However, if one of the tests succeeds, _reset_sig_warn() is never called because the for loop is exited via the last instruction. I've corrected this in my local installation by rewriting the code as below:
foreach my $hash_i ( @hashes ) {
foreach my $search_i ( @search ) {
my ($name , $type , $value) = @{$search_i} ;
$type =~ s/\s//gs ;
$i++ ;
my $hash ;
if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;}
else { $hash = $hash_i ;}
my $data ;
if ($name =~ /^content$/i) { $name = 'CONTENT' ;}
$data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ;
$data = $$data{CONTENT} if ref($data) eq 'HASH' ;
_unset_sig_warn() ;
my $last;
if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; $last = 1 ;}
_reset_sig_warn() ;
last if ($last);
}
With this fix the second warn message in your test example is displayed.