Perl Module(s) Of The Week - 2019 Week 03 - MP3::Daemon

They said, old habits dies hard, especially if you're coming from console background. The tendency of trying to do everything at the console is hard to break. Console programs in *nix worlds tends to follow the Unix philosophy of do one thing and do it well, work well with other programs, and exchange data using text stream. The Perl module of this week, MP3::Daemon, a text front end to mpg123, was designed to follow such philosophy. For example, play part of a MP3 file repeatedly.
while true ; do mp3 j 1300 ; sleep 386 ; done

Installation and quick run of the program.
$ cpanm MP3::Daemon
$ mp3

Trying to run one of the command and we encountered these error messages. Note that this program was first written in 2001, 18 years ago, maybe there was some bugs or maybe it was due to my local installation. Furthermore, following recent naming convention, the module should have been named `App::MP3`. However, looking and reading old code will give you some insights on writing Perl code without resorting to external modules but focus on just basic Perl code. Nevertheless, we try to resolve these two issues.
 $ mp3 ls
Subroutine main::pod2usage redefined at (eval 16) line 1.
 main::BEGIN() called at (eval 16) line 1
 eval {...} called at (eval 16) line 1
 eval 'use Pod::Usage' called at /home/foobar/perl5/bin/mp3 line 8
No such file or directory at /home/foobar/perl5/lib/perl5/MP3/Daemon.pm line 84.

We first look into the `No such file or directory` error. Looking through the source code at line 84, educated guess that `mpg123` program (the program was name after the MPEG layer 1/2/3 format) have not been installed. Installed the console app will remove the error message.
$ sudo apt install mpg321

If you cannot access the source code, you can jump to the particular line using `less`. The `+84` option will jump to line 84 and `-N` will show line numbers.
$ less +84 -N /home/foobar/perl5/lib/perl5/MP3/Daemon.pm

For second issue on subroutine redefined error. Looking through the source code as shown below. In Perl, without using external modules, we use `eval` for exception handling. The code checks for `Pod::Usage` availability, if not found, set the error message to `[email protected]`, the eval error variable.
eval "use Pod::Usage";
if ([email protected]) {
    sub pod2usage { system("perldoc mp3"); exit 1 }
}

To resolve this issue, first we need to enable `diagnostics` module to give us hints on what and how to resolve this warning. Add this line to the `mp3` executable script.
use diagnostics -verbose;

Run this program again. We will obtain full verbose details on the warning and how to resolve it.
DESCRIPTION OF DIAGNOSTICS
    These messages are classified as follows (listed in increasing order of
    desperation):
    
        (W) A warning (optional).
        (D) A deprecation (enabled by default).
        (S) A severe warning (enabled by default).
        (F) A fatal error (trappable).
        (P) An internal error you should never see (trappable).
        (X) A very fatal error (nontrappable).
        (A) An alien error message (not generated by Perl).
    
    The majority of messages from the first three classifications above
    (W, D & S) can be controlled using the warnings pragma.
    
    If a message can be controlled by the warnings pragma, its warning
    category is included with the classification letter in the description
    below.  E.g. (W closed) means a warning in the closed category.
    
    Severe warnings are always enabled, unless they are explicitly disabled
    with the warnings pragma or the -X switch.
    
    Trappable errors may be trapped using the eval operator.  See
    "eval" in perlfunc.  In almost all cases, warnings may be selectively
    disabled or promoted to fatal errors using the warnings pragma.
    See warnings.
    

Subroutine main::pod2usage redefined at (eval 17) line 1.
 main::BEGIN() called at (eval 17) line 1
 eval {...} called at (eval 17) line 1
 eval 'use Pod::Usage' called at /home/foobar/perl5/bin/mp3 line 9 (#1)
    (W redefine) You redefined a subroutine.  To suppress this warning, say
    
        {
            no warnings 'redefine';
            eval "sub name { ... }";
        }

Made changes to the program as follow and the warning should be disabled.
  8 eval "use Pod::Usage";
  9 if ([email protected]) {
 10     {
 11         no warnings 'redefine';
 12         eval qq/sub pod2usage { system("perldoc mp3"); exit 1 };/                                          
 13     }
 14 }




No comments:

Post a Comment