[sf-perl] conditional "no warnings 'threads'"

David Christensen dpchrist at holgerdanske.com
Sat Aug 1 00:10:10 PDT 2020


sanfrancisco-pm:

I have a Linux computer:

2020-07-31 23:24:49 dpchrist at tinkywinky ~/sandbox/perl
$ cat /etc/debian_version ; uname -a ; perl -v | head -n 3
9.13
Linux tinkywinky 4.9.0-12-amd64 #1 SMP Debian 4.9.210-1+deb9u1 
(2020-06-07) x86_64 GNU/Linux

This is perl 5, version 24, subversion 1 (v5.24.1) built for 
x86_64-linux-gnu-thread-multi
(with 90 registered patches, see perl -V for more detail)


I am working on a Perl 5 library that uses threads.  If code in a child 
thread throws an exception, I want the exception message to be printed; 
except during testing.


I have found that:

     no warnings 'threads'

when placed before, and in the same block as, threads->create() will 
suppress printing of the exception message:

2020-07-31 23:43:08 dpchrist at tinkywinky ~/sandbox/perl
$ cat thread-exception.pl
#!perl

use strict;
use warnings;
use threads;

use Test::More;
use Test::Exception;

our $thr;
our $test_mode;

sub foo
{
     if ($test_mode) {
	no warnings 'threads';

	$thr = threads->create(
	    sub { die "hello, world!" }
	);
     } else {
	$thr = threads->create(
	    sub { die "hello, world!" }
	);
     }
}

ok foo, __FILE__ . __LINE__;				# 1

is $thr->join, undef, __FILE__ . __LINE__;		# 2

like $thr->error, qr/hello/, __FILE__ . __LINE__;	# 3

$test_mode = 1;

ok foo, __FILE__ . __LINE__;				# 4

is $thr->join, undef, __FILE__ . __LINE__;		# 5

like $thr->error, qr/hello/, __FILE__ . __LINE__;	# 6

done_testing;

2020-07-31 23:43:11 dpchrist at tinkywinky ~/sandbox/perl
$ perl thread-exception.pl
Thread 1 terminated abnormally: hello, world! at thread-exception.pl 
line 23.
ok 1 - thread-exception.pl28
ok 2 - thread-exception.pl30
ok 3 - thread-exception.pl32
ok 4 - thread-exception.pl36
ok 5 - thread-exception.pl38
ok 6 - thread-exception.pl40
1..6


I was unable to figure out how to conditionally perform "no warnings 
'threads'" in the body of foo(), so I had to copy-and-paste the body 
into both halves of an if-else conditional and disable warnings in one 
block.  This is an ugly work-around.


I was hoping for:

     no warnings 'threads' if $test_mode;	# BAD CODE


But, that code does not work;

2020-07-31 23:56:50 dpchrist at tinkywinky ~/sandbox/perl
$ cat no-warnings-threads-if-1.pl
#!perl

use strict;
use warnings;

no warnings 'threads' if 1;

2020-07-31 23:56:53 dpchrist at tinkywinky ~/sandbox/perl
$ perl no-warnings-threads-if-1.pl
syntax error at no-warnings-threads-if-1.pl line 6, near "'threads' if"
Execution of no-warnings-threads-if-1.pl aborted due to compilation errors.


Any comments or suggestions?


David


More information about the SanFrancisco-pm mailing list