12

I am trying to use the following conventions I have been instructed to use for good/proper/safe Perl code for my "Hello, World!" Program:

use strict;
use warnings;

I have created and successfully run the following "Hello World" program using (Strawberry) Perl 5.12 on my main Windows 7 OS:

!#/usr/bin/perl
use strict;
use warnings;

print "Hello, World!\n";

What I got back, as expected, was "Hello, World!".

What struck me as very odd was that the same program run in terminal on my virtualized Linux Mint 14 OS, using Perl 5.14, produced the following error:

"use" not allowed in expression at /PATH/hello_world.pl line 2, at end of line
syntax error at /PATH/hello_world.pl line 2, near "use strict"
BEGIN not safe after errors--compilation aborted at /PATH/hello_world.pl line 3.

I created other "Hello World" programs subsequently without either the use strict; or use warnings; lines, and also one with the -w, which I had seen in some tutorials, indicating, if I am not mistaken, that warnings would be turned on.

Both of my alternate versions worked properly in that they produced my expected result:

Hello, World!

What I cannot be sure of is if I need the use statements in Perl programs from version 5.14 and up or if it is just fine to write the -w at the end of my first line.

I would like to think that I could use a consistent header, so to speak, in all of my Perl programs, whether they are Windows or Linux, Perl 5.12 or 5.14 or otherwise.

doubleDown
  • 8,048
  • 1
  • 32
  • 48
bc1984adam
  • 173
  • 1
  • 9
  • 5
    Did you ftp this to your Linux box? Did you use text mode? – Edward Thomson Jan 13 '13 at 07:19
  • 4
    "use" is very definitely allowed :) The problem is something else - perhaps, as Edward Thomson is suggesting, your source file got corrupted when you ftp'ed it from one PC to another. – paulsm4 Jan 13 '13 at 07:27
  • Did not FTP. Using VirtualBox with Linux Mint 14. Not using text mode. – bc1984adam Jan 13 '13 at 22:10
  • I created a screenshot to show my attempts with different versions of my "Hello, World!" program here: [link](http://bayimg.com/haiBMAAej). – bc1984adam Jan 13 '13 at 22:49

2 Answers2

17

Your image shows that all of your scripts start with !#/usr/bin/perl. This is wrong. It is not a valid she-bang line, it is read as negation ! followed by a comment #. The parsing will continue and with script1.pl perl will execute ! print "Hello world.\n";. This will print Hello world and negate the result of print ... not really useful, but valid perl.

In script2.pl perl sees ! use strict; and this is a compile time error and therefor perl fails and reports the error for the line use strict;.

So if you use correct she-bang lines, all three scripts will work as designed.

Edit (test scripts added):

script1.pl

!#/usr/bin/perl

print "Hello world.\n" ;

Calling perl script1.pl gives

Hello world.

script2.pl

!#/usr/bin/perl

use strict;
use warnings ;

print "Hello world.\n" ;

Calling perl script2.pl gives

"use" not allowed in expression at script2.pl line 3, at end of line
syntax error at script2.pl line 3, near "use strict "
BEGIN not safe after errors--compilation aborted at script2.pl line 4.

Using the correct syntax script3.pl

#!/usr/bin/perl

use strict ;
use warnings ;

print "Hello world.\n" ;

Calling perl script3.pl gives

Hello world.
dgw
  • 13,418
  • 11
  • 56
  • 54
  • Why the downvote? This is the cause of the problem here. I could verify it. – dgw Jan 14 '13 at 08:58
  • 3
    Your *script1.pl* doesn't ignore the wrong shebang line, because obviously when you write `!#` it isn't a shebang line. It's the `!` (not) operator, followed by a comment. So it's the same as writing `!print`: inverting the return value of the `print` statement — which of course is ignored anyway. Where as in *script2.pl* it's doing `!use`, which doesn't make sense because `use` is a compile-time construct, not a run-time function. – Smylers Jan 14 '13 at 09:54
  • @Smylers You are right, I changed my answer to give the correct reason for the failure. Thanks. – dgw Jan 14 '13 at 12:26
  • Thanks for the help! I feel so much better knowing that I just made a simple mistake! – bc1984adam Jan 15 '13 at 07:01
9

You did something like

use warnings
use strict;

instead of

use warnings;
use strict;

Actually, I think it might be a line ending issue. You have LF where you should have CR LF or vice-versa. I've seen this cause Perl to think the code starts halfway through the shebang line (e.g. perl use strict;)


As mentioned elsewhere, the code you posted and the code you used is different. You actually used

!use strict;

due to a bad shebang line.

!#/u...         # Negation followed by a comment

should be

#!/u...         # Shebang
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Is there any way I can test this by adding an extra line break at the end of the shebang line? Could I use "\n"? – bc1984adam Jan 13 '13 at 22:56
  • I tested with `-w` at the end of the shebang line, and with `"\n"` as well, and neither changed the output/error. I found the following [document](https://community.plus.net/forum/index.php?topic=43650.0;prev_next=next) which discusses how to deal with CR/LF issues between Windows and Linux. Again, I tried warning mode, which it suggests you implement in order to prevent the issue you've just mentioned from happening, but nothing changed. I don't see why I would have a CR LF issue writing and running these basic programs on a fresh linux install, though. I didn't FTP them at all. – bc1984adam Jan 14 '13 at 00:18