Autodie fools syntaxcheck of perl - perl

Seems as if depending on the version of perl, autodie masks some syntax-errors.
In Perl 5.16.0:
$ perlbrew use 5.16.0
$ perl -c check_netapp_pro/lib/Il/Nagios/test/xx.pm
String found where operator expected at check_netapp_pro/lib/Il/Nagios/test/xx.pm line 10, near "croak "stop""
(Do you need to predeclare croak?)
syntax error at check_netapp_pro/lib/Il/Nagios/test/xx.pm line 10, near "croak "stop""
check_netapp_pro/lib/Il/Nagios/test/xx.pm had compilation errors.
But in 5.10.1:
$ perlbrew use 5.10.1
$ perl -c check_netapp_pro/lib/Il/Nagios/test/xx.pm
check_netapp_pro/lib/Il/Nagios/test/xx.pm syntax OK
The module xx.pm is:
package Il::Nagios::Store::Attribute;
use feature ':5.10';
use strict;
use warnings;
use autodie;
#use Carp;
croak "stop" if 0;
1;
__END__
The confusing part is that on some servers (e.g. CentOS 6.5, perl 5.10.1) the absence of use Carp; stops script execution even if use autodie; is present in the module.
Can anyone shed some light on this? How would you unit-test against such errors? (Test::Strict did not detect the missing use Carp; statement).

Thanks to the comment from #i-alarmed-alien I could quickly determine the reason:
On my 5.10.1 perlbrew installation autodie is installed with version 2.06_01, the newer installation (perl 5.16.0) is using autodie in version 2.10 where a bug had been fixed, which leaked the Carp functions.
Just for the records: To determine the version of autodie (or any other module) just type
cpan -D autodie

Related

Perlbrew cannot run simple scripts IPC::System::Simple required for Fatalised/autodying system()

I am a new perlbrew user, as I wish to upgrade to perl 5.30.0 on Ubuntu.
I have done
perlbrew init
perlbrew install perl-5.30.0
perlbrew switch perl-5.30.0
so I try to run this test script:
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':all';
but this gives the long error
IPC::System::Simple required for Fatalised/autodying system() at /home/con/Scripts/say.pl line 6.
main::BEGIN() called at /home/con/Scripts/say.pl line 6
eval {...} called at /home/con/Scripts/say.pl line 6
BEGIN failed--compilation aborted at /home/con/Scripts/say.pl line 6.
Command exited with non-zero status 2
I thought that libraries (especially standard ones) were supposed to be loaded automatically via perlbrew? How can I get this simple script to run?
From autodie we see that it's documented behavior
If system is specified as an argument to autodie, then it uses
IPC::System::Simple to do the heavy lifting. See the description of that
module for more information.
So one does need IPC::System::Simple installed for :all tag (which implies system).
It strikes me as curious that a core functionality requires a non-core module, and quietly too (doesn't complain at installation).
I'm getting exactly the same error on a non-perlbrew Perl. It seems autodie requires IPC::System::Simple when running under fatal warnings or with :all, but it doesn't require it during installation.
See also https://bugzilla.redhat.com/show_bug.cgi?id=1183231.
The solution, according to #ikegami, and that worked for me: /home/con/perl5/perlbrew/perls/perl-5.30.0/bin/perl -e'use IPC::System::Simple'; /home/con/perl5/perlbrew/perls/perl-5.30.0/bin/cpan IPC::System::Simple; /home/con/perl5/perlbrew/perls/perl-5.30.0/bin/perl -e'use IPC::System::Simple'
of course, for anyone in the future, this will be slightly different for you, as your directories may be set differently, and username isn't con

Perl: par packer executable with Unicode::GCString, Can't locate object method "new"

I'm using the PAR::Packer module to create a Windows executable of a Perl script that uses the Unicode::GCString module.
A stripped down version of the script is as follows:
mwe.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Unicode::GCString;
my $gcs = Unicode::GCString->new("hello world");
print $gcs->columns();
exit(0);
When I run
perl mwe.pl
the output gives the 'width' of the string:
11
which is as expected.
I create mwe.exe using the command
pp -o mwe.exe mwe.pl
and when I run
mwe.exe
I receive the error
Can't locate object method "new" via package "Unicode::GCString" at
script/mwe.pl line 6
Having reviewed AppData\Local\Temp\par-xxxxxx\cache-xxxxx\inc\lib, I believe that Unicode::GCString is present, as is Unicode::LineBreak.
Does anyone have any ideas on how to fix this?
A solution can be to use this version of "pp" I call it "ppp.pl"
$ENV{PAR_VERBATIM}=1;
system 'pp', #ARGV;
Details at https://metacpan.org/pod/distribution/PAR/lib/PAR/Environment.pod#PAR_VERBATIM
The cause is related to this bug Bug #38271 for PAR-Packer: PodStrip does not strip "=encoding utf8" which cause the executable generated by pp failed to exec
Also the boilerplate inside Unicode::GCString

Why would one put `#! /usr/bin/false` in a Perl Module?

I was looking at the source code for the CPAN Perl module Digest::Perl::MD5 and noticed that it has the she bang #! /usr/bin/false. Here's the first few lines of Digest/Perl/MD5.pm ...
#! /usr/bin/false
#
# $Id: MD5.pm,v 1.19 2004/02/14 02:25:32 lackas Exp $
#
package Digest::Perl::MD5;
use strict;
use integer;
use Exporter;
use vars qw($VERSION #ISA #EXPORTER #EXPORT_OK);
... why would the author of Digest::Perl::MD5 use #! /usr/bin/false? And what if my system does not have /usr/bin/false but has /bin/false instead?
why would the author of Digest::Perl::MD5 use #! /usr/bin/false?
So that if someone tried to use the module as an executable (Perl $ ./MD5.pm), it would quietly die instead of trying to execute the module as a program.
And what if my system does not have /usr/bin/false but has /bin/false instead?
Then it will nosily die complaining that it couldn't find /usr/bin/false if anyone tried that.

Why is "use" not allowed, as in "use strict;" in Perl 5.14?

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.
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.
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

Gitolite on Dreamhost

I'm trying to install Gitolite as in the http://wiki.dreamhost.com/Gitolite
I get the error like :
"make_path" is not exported by the File::Path module
Can't continue after import errors at gitolite/src/gl-system-install line 5
BEGIN failed--compilation aborted at gitolite/src/gl-system-install line 5.
There is a problem with perl but I could not find solution yet.
server capabilities
/usr/local/bin/perl
perl v5.10.0
make_path was introduced in File::Path 2.06_05. You must be using an older version (Perl 5.10.0 came with File::Path 2.04). Upgrade File::Path (or upgrade Perl, since 5.10 is no longer supported).
At press time, gl-system-install calls make_path in one place, in the sub that begins at line 75:
sub check_dirs {
for my $dir ( $bin_dir, $conf_dir, $hooks_dir ) {
die "$dir should be an absolute path\n" unless $dir =~ m(^/);
make_path($dir);
-d $dir or die "$dir does not exist and could not be created\n";
}
}
This particular usage is call-compatible with mkpath instead. You don’t have to install a new File::Path module. Change line 5 of gl-system-install to
use File::Path qw(mkpath);
and line 78 to
mkpath($dir);
I encountered the same situation within the last week. After making the changes above, you can follow gitolite’s installation instructions with no further snags.
Update: This issue is now fixed in the gitolite repository.
make_path is only available in File::Path 2.07. I'm not sure if it's your problem or not, but you might try updating File::Path:
cpan File::Path
or
cpanp i File::Path