Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do these two warnings about comments and prototypes mean in Perl?

Tags:

perl

I have the following code

#! /usr/bin/perl

use strict;
use warnings;

################### Start Main ####################
my @startupPrograms = qw(google-chrome thunderbird skype pidgin );
my @pagesToBeOpenedInChrome = qw(http://www.google.com/ http://stackoverflow.com/ https://mail.google.com/mail/u/0/#inbox);
main();


#################################################

sub main() {

}

and I get following warning

[aniket@localhost TestCodes]$ ./test.pl 
Possible attempt to put comments in qw() list at ./test.pl line 8.
main::main() called too early to check prototype at ./test.pl line 9.

Program works fine but I am not able to understand the warnings. What do they mean?

like image 995
Aniket Thakur Avatar asked Aug 23 '13 11:08

Aniket Thakur


3 Answers

This warning:

Possible attempt to put comments in qw() list at ./test.pl line 8.

Refers to this part of the specified line:

.... https://mail.google.com/mail/u/0/#inbox);
                                 # ---^

The # sign is a comment in Perl, and qw() has a few special warnings attached to it. It's nothing to worry about, but it does look like a redundant warning in this case. If you want to fix it you can enclose the assignment in a block and use no warnings 'qw'. This is however somewhat clunky with a lexically scoped variable:

my @pages;    # must be outside block
{
    no warnings 'qw';
    @pages = qw( .... );
}

I have some doubts about the usefulness of warnings 'qw', and in a small script you can just remove the pragma globally by adding no warnings 'qw' at the top of the script.

This warning:

main::main() called too early to check prototype at ./test.pl line 9.

This has to do with the empty parentheses after your sub name. They denote that you wish to use prototypes with your subroutine, and that your sub should be called without args. Prototypes are used to make subroutines behave like built-ins, which is to say its not something you really need to worry about, and should in almost all cases ignore. So just remove the empty parentheses.

If you really, truly wish to use prototypes, you need to put either a predeclaration or the sub declaration itself before the place you intend to use it. E.g.

sub main ();  # predeclaration

main();

sub main () {
}
like image 184
TLP Avatar answered Nov 26 '22 17:11

TLP


In the first warning Perl complains about the hash in the quote operator:

my @foo = qw(foo bar #baz);

Here the hash is a part of the last URL and Perl thinks you maybe wanted to place a comment there. You can get rid of the warning by quoting the items explictly:

my @foo = (
    'first URL',
    'second URL',
    'and so on',
);

It’s also more readable IMHO, the qw(…) construct is better fit for simpler lists only.

The second warning is a bit weird, because Perl obviously knows about the sub, otherwise it would not complain. Anyway, you can drop the () part in the sub definition, and everything will be OK:

sub main {
}

The () here does something else than you think, it’s not needed to define a simple sub. (It’s a sub prototype and most probably you don’t want to use it.) By the way, there’s no need at all to declare a main sub in Perl, just dump whatever code you need there instead of the sub definition.

like image 30
zoul Avatar answered Nov 26 '22 16:11

zoul


Possible attempt to put comments in qw() list at ./test.pl line 8.

This warning complains because you have a # in your quoted words list. The # starts a comment in Perl. The warning lets you know that you might have put a comment in there by mistake.

                                                                                     v
qw(http://www.google.com/ http://stackoverflow.com/ https://mail.google.com/mail/u/0/#inbox);
like image 44
simbabque Avatar answered Nov 26 '22 18:11

simbabque