What do these two warnings about comments and prototypes mean in 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?

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 () {
}

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.


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);

To remove the second warning

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

you can call the main() method with &main()

&main();
^
#################################################
sub main() {

}

Need Your Help

How to assign number for many level subtitles using Loop in Java?

java loops

A user can provide a String[] holding title & its level via keyboard. Ex: user can type History, Level 1 at keyboard level then the system will make up an array String[] strArray={"History","Le...

Crontab not able to write into a file

unix sendmail crontab

I have disk cleanup script. Below is the initial part of the sendmail function which writes into one html file and then mail it using sendmail.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.