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

The file below, with two lines commented out, works as I expect.

use strict; use warnings; package Sscce; use Getopt::Long; use Pod::Usage; my ($opt_help, $opt_man, ); # sub main { GetOptions( 'help' => \$opt_help, 'man' => \$opt_man, ) or pod2usage(-verbose => 1) && exit; pod2usage(-verbose => 1) && exit if defined $opt_help; pod2usage(-verbose => 2) && exit if defined $opt_man; # } 1; =pod =head1 NAME =head1 ARGUMENTS =head1 OPTIONS --help Brief manual --man Full manual

Running the file gives the output below:

X:\Data\Perl\NoFile>perl Sscce.pm -h Arguments: Options: --help Brief manual --man Full manual X:\Data\Perl\NoFile>perl Sscce.pm -m NAME ARGUMENTS OPTIONS --help Brief manual --man Full manual

But if the two comment lines are uncommented and the calling command changed, I get an error:

X:\Data\Perl\NoFile>Perl -I. -MSscce -e"Sscce::main @ARGV" -- -h Can't open -e: No such file or directory at Sscce.pm line 17.

I fear that I have no idea how to approach this. Adding diagnostics gives more data:

X:\Data\Perl\NoFile>Perl -I. -MSscce -e"Sscce::main @ARGV" -- -h Can't open -e: No such file or directory at Sscce.pm line 18 (#1) (S inplace) The implicit opening of a file through use of the <> filehandle, either implicitly under the -n or -p command-line switches, or explicitly, failed for the indicated reason. Usually this is because you don't have read permission for a file which you named on the command line. (F) You tried to call perl with the -e switch, but /dev/null (or your operating system's equivalent) could not be opened. Uncaught exception from user code: Can't open -e: No such file or directory at Sscce.pm line 18. Pod::Simple::parse_file(Pod::Usage=HASH(0x262f6a8), "-e") call +ed at C:/Strawberry/perl/lib/Pod/Text.pm line 737 Pod::Text::parse_file(Pod::Usage=HASH(0x262f6a8), "-e") called + at C:/Strawberry/perl/site/lib/Pod/Simple.pm line 535 Pod::Simple::parse_from_file(Pod::Usage=HASH(0x262f6a8), "-e", + GLOB(0x2623f40)) called at C:/Strawberry/perl/lib/Pod/Text.pm line 7 +06 Pod::Text::parse_from_file(Pod::Usage=HASH(0x262f6a8), "-e", G +LOB(0x2623f40)) called at C:/Strawberry/perl/lib/Pod/Usage.pm line 17 +9 Pod::Usage::pod2usage("-verbose", 1) called at Sscce.pm line 1 +8 Sscce::main(GLOB(0x2623f40)) called at -e line 1

Unfortunately, going through the code points listed has left me none the wiser. I'd be grateful for any help.

Regards,

John Davies

Replies are listed 'Best First'.
Re: Wrapping code in a sub causes an error I don't understand.
by haukex (Archbishop) on Aug 30, 2023 at 21:44 UTC

    Note the error happens regardless of the presence of the sub main; that's not what's causing it, instead it is Pod::Usage trying to read the POD. From its documentation (emphasis mine):

    -input handle
    A reference to a filehandle, or the pathname of a file from which the invoking script's pod documentation should be read. It defaults to the file indicated by $0 ($PROGRAM_NAME for users of English.pm).

    And when you run Perl with the -e switch, the $0 variable will be "-e", which is where the error message is coming from; it's trying to open a file with that name. The documentation further goes on to state:

    If you are calling pod2usage() from a module and want to display that module's POD, you can use this:
    use Pod::Find qw(pod_where); pod2usage( -input => pod_where({-inc => 1}, __PACKAGE__) );

    Which, when applied to your example code, works for me.

      And it works for me. Thank you. I was, as you have spotted, floundering and it would have taken me a very long time to find your answer on my own.

      Regards,

      John Davies

Re: Wrapping code in a sub causes an error I don't understand.
by hv (Prior) on Aug 30, 2023 at 23:23 UTC

    Given the other comments, it seems to me that Pod::Usage could spot this case and give a more useful error message. It may be worth filing a feature request via the module's github with a reference back to this thread.

Re: Wrapping code in a sub causes an error I don't understand.
by hippo (Archbishop) on Aug 30, 2023 at 21:51 UTC

    I don't use Pod::Usage, so take this with a large pinch of salt.

    The documentation says:

    CAVEATS

    By default, pod2usage() will use $0 as the path to the pod input file.

    And in the case of calling it not as a script but with -e as you have done, then $0 becomes -e so Pod::Usage fails to open that file. The short answer is either don't use Pod::Usage or don't call it like that.

    Additionally, pod2usage should exit so all of those && exit clauses would seem to be superfluous.


    🦛

        Thanks for the reference. There was already a reply in that thread discussing the unnecessary use of && exit and I've added my tuppence here.


        🦛