Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Turn off FATAL warnings in 3rd party module

by bliako (Monsignor)
on Jun 03, 2019 at 14:07 UTC ( [id://11100873]=perlquestion: print w/replies, xml ) Need Help??

bliako has asked for the wisdom of the Perl Monks concerning the following question:

I have trouble turning OFF the effect of use warnings FATAL => 'all'; which is found inside a 3rd party module of which I have no control. Said module is Tree.

Here is my attempt:

use strict; use warnings; use Tree; use warnings NONFATAL => 'all'; my ($i, $T, $n); $T = Tree->new('root'); my $t = $T; for($i=0;$i<100;$i++){ $n = Tree->new("child $i"); $t->add_child({}, $n); $t = $n; } print "success\n";

Which dies with the now-fatal warning: Deep recursion on subroutine "Tree::_fix_height"

So, how to turn it off from within my script assuming I can not change the module source code?

Edit: Tree's version is 1.13, the latest, Perl's version is 5.26.2

Replies are listed 'Best First'.
Re: Turn off FATAL warnings in 3rd party module
by Eily (Monsignor) on Jun 03, 2019 at 15:21 UTC

    If disabling the warning altogether doesn't work, the next best thing would be to not use the module at all IMHO. The doc on Fatal Warnings is quite explicit about the fact that use warnings FATAL => 'all'; is a bad idea. One obvious replacement for this module is to just copy it without the problematic line, since it's a pure perl module.

    I would actually avoid just catching the exception though. Because the exception means the function add_child has been interrupted before finishing, so the state of the object is not guarranteed to be correct (eg: _fix_width hasn't been called at all).

    Edit: or just let the author fix his module. I should be more patient and not always jump to the fastest fix so carelessly. Thanks to stevieb and ron.savage for the actual correction :D

      Hi Stevieb9 submitted a git pull request re this issue, which I've accepted. So, V 1.14 is now on CPAN.

      Good point Eily about no guarantees add_child() has finished what's supposed to be doing without interruption if I enclose the offending statement in eval {}. The warning causes a die after all. For the record, it does seem to add the child beyond 99 and fails in doing the necessary housekeeping.

      Also, even if it succeeds in the small script I provided, in my real use-case I must eval each and every Tree method just in case it runs over the recursion limit.

      So, I am not doing the eval. I am looking for a replacement module (any suggestions) and filing a request to author.

        "I am looking for a replacement module (any suggestions) and filing a request to author."

        I'd simply fork the repo, create a new branch, make your change, and install the updated distribution manually from your repository. Then, in Github, create a Pull request (PR) with your updated branch for possible inclusion into the original software.

        If you're unfamiliar with that process, let me know and I'll quickly do it for you, and provide you a link to the updated repo for you to install from.

Re: Turn off FATAL warnings in 3rd party module
by toolic (Bishop) on Jun 03, 2019 at 14:59 UTC
    I don't know if you can disable the warning without modifying the source code, but one way to capture the warning is to use eval
    use strict; use warnings; use Tree; my ($i, $T, $n); $T = Tree->new('root'); my $t = $T; for($i=0;$i<100;$i++){ $n = Tree->new("child $i"); eval { $t->add_child({}, $n); }; if ($@) { # take some action... } $t = $n; } print "success\n";

    Then you can decide what action to take.

    My guess is that the NONFATAL attempt did not work because it is in the wrong scope; NONFATAL would have to be used inside the Tree module.

Re: Turn off FATAL warnings in 3rd party module
by thanos1983 (Parson) on Jun 03, 2019 at 15:05 UTC

    Hello bliako,

    If you enable use diagnostics; you will see the following:

    $ perl test.pl Deep recursion on subroutine "Tree::_fix_height" at /usr/local/share/perl/5.26.2/Tree.pm line 333 (#1) (W recursion) This subroutine has called itself (directly or indir +ectly) 100 times more than it has returned. This probably indicates an infinite recursion, unless you're writing strange benchmark progra +ms, in which case it indicates something else. This threshold can be changed from 100, by recompiling the perl bi +nary, setting the C pre-processor macro PERL_SUB_DEPTH_WARN to the desir +ed value. Uncaught exception from user code: Deep recursion on subroutine "Tree::_fix_height" at /usr/local/sha +re/perl/5.26.2/Tree.pm line 333. Tree::_fix_height(Tree=HASH(0x5614409803c0)) called at /usr/local/ +share/perl/5.26.2/Tree.pm line 333 Tree::_fix_height(Tree=HASH(0x561440992cc8)) called at /usr/local/ +share/perl/5.26.2/Tree.pm line 333 . . .

    The error is not on the module Tree it is the limit that Perl has by default for recursions.

    (W recursion) This subroutine has called itself (directly or indir +ectly) 100 times more than it has returned.

    The only way to modify this is:

    This threshold can be changed from 100, by recompiling the perl binary +, setting the C pre-processor macro PERL_SUB_DEPTH_WARN to the desir +ed value.

    Unfortunately this is not a local modification of the module it will affect the Perl binary on you OS.

    I will keep looking into it in case I will find something more than that, I will update the post. I am sure other Monks will have much deeper knowledge on this.

    Update: If you change the format on the way you add child and you add specific position to the function add_child() the loop will not become recursive. The function will return TRUE after execution and you will not have this problem. Sample of code from the module documentation Tree "modified slightly to your needs":
    #!/usr/bin/perl use strict; use warnings; use Tree; my $tree = Tree->new('root'); foreach my $i (0..200){ $tree->add_child( { at => $i }, Tree->new( "child $i" ) ); } print "success\n"; __END__ $ perl test.pl success

    BR / Thanos

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Turn off FATAL warnings in 3rd party module
by daxim (Curate) on Jun 03, 2019 at 15:03 UTC
    Simply trap the exception (== fatal warning), that's more straight-forward than monkey-patching Tree at run-time. Wrap the statement calling add_child in eval {} or use an exception handler like Try::Tiny.
Re: Turn off FATAL warnings in 3rd party module
by holli (Abbot) on Jun 03, 2019 at 15:07 UTC
    Does it still return the right thing? If so, do as toolic says, if not you could try disable that warning completely. (That node is from 2004 though, chances are it won't work anymore)


    holli

    You can lead your users to water, but alas, you cannot drown them.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11100873]
Approved by marto
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (7)
As of 2024-04-18 09:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found