develooper Front page | perl.perl5.porters | Postings from April 2006

op/pat.t: patterns that warn when compiled

David Landgren
April 25, 2006 03:16
op/pat.t: patterns that warn when compiled
Message ID:
I've been looking at t/op/pat.t, and there's a bit of code that I think 
isn't doing what people think it should be doing, but as it involves 
closures within closures I would like a second opinion. Consider 

sub must_warn_pat {
     my $warn_pat = shift;
     return sub { print "not " unless $_[0] =~ /$warn_pat/ }

sub must_warn {
     my ($warn_pat, $code) = @_;
     local %SIG;
     eval 'BEGIN { use warnings; $SIG{__WARN__} = $warn_pat };' . $code;
     print "ok $test\n";

sub make_must_warn {
     my $warn_pat = shift;
     return sub { must_warn(must_warn_pat($warn_pat)) }

my $for_future = make_must_warn('reserved for future extensions');

&$for_future('q(a:[b]:) =~ /[x[:foo:]]/');


I understand this to be setting up a generator that evaluates wonky 
regexps and ensures that the warnings it emits are what is expected.

As far as I can tell, all this always returns true. First, 
make_must_warn generates a sub, but the argument that gets passed to, 
for example, $for_future when invoked never goes anywhere. It seems to 
me that make_must_warn() ought to be written as

sub make_must_warn {
     my $warn_pat = shift;
     return sub { must_warn(must_warn_pat($warn_pat), shift) }

... because $code never gets set to anything in must_warn(). Thus the 
eval() never fails, (cause it ain't doing anything, never mind trigger 
the warning handler). Secondly,

     q(a:[b]:) =~ /[x[:foo:]]/

is a fatal croak anyway, thus the &$for_future call should be commented 
out (like the two following tests) and the whole question is moot. Or 
it's a fatal croak but should really be warning that the construct is 
reserved for future use, I dunno.

"It's overkill of course, but you can never have too much overkill." Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About