cpan vs -MCPAN - Perl - windows

I'm currently running bash via Cygwin on Windows, and I've come across two different ways to install a Perl module
cpan Name::Module
and
perl -MCPAN -e shell
install Name::Module
What's the difference between these two methods, and do they offer any advantages or disadvantages over the other?

cpan installs for the perl in the shebang (#!) line of the cpan file.
When someone has more than one perl installed on a machine, they sometimes run the wrong copy of cpan, and thus end up installing modules for the wrong instance of perl.
One solution to that would be to specify the full path to the correct cpan file.
perl -MCPAN -e shell is the other solution. It allows you to explicitly specify the install of perl for which you want the modules to be installed.

cpan on Windows just calls App::Cpan->run( #ARGV ), which should give you the same shell as the other command, maybe with other settings active. But I think it's the same. So you could use both. I prefer just cpan and then do install Name::Module, since I tend to look if it's installed before and which version in the cpan shell beforehand.

Related

Running perl script with Scalar::Util fails with "Attempt to reload Scalar/Util.pm aborted."

I have recently switched to a Mac Book Pro M1 (from Ubuntu) and installed Perl from homebrew.
I've installed a number of perl packages I commonly use without any issues. Unfortunately at runtime any perl programs that depend on (or use a package that depends on) Scalar::Util or List::Util fail with errors like:
Attempt to reload Scalar/Util.pm aborted.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/YAML.pm line 21.
...
or
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/Scalar/Util.pm line 23.
I've also tried to install perlbrew as an alternative but haven't succeeded there. I've also checked that everything appears in the PERL5LIB path correctly.
With List::Util I've managed to install a newer version from CPAN but still get the same error. (The builtin Scalar::Util is the latest version)
Any suggestions on what to try to get them working I fear that it's an M1 issue but I'm not sure it could be an xcode issue I guess.
You can replicate this with:
$ cpanm VCSL::Which
$ vcsvimdiff -v
Can't load '/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace (_Perl_croak_memory_wrap) at /System/Library/Perl/5.30/XSLoader.pm line 96.
at /opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0/darwin-thread-multi-2level/List/Util.pm line 24.
Compilation failed in require at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.
BEGIN failed--compilation aborted at /opt/homebrew/Cellar/perl/5.34.0/bin/vcsvimdiff line 12.
Unfortunately running
perl -MScalar::Util -e 1
or
perl -MList::Util -e 1
both run successfully. I looked at my PERL5LIB path and only see the homebrew perl paths there.
$ perl -E 'say join "\n", split /:/, $ENV{PERL5LIB}'
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5
/opt/homebrew/Cellar/perl/5.34.0/lib/perl5/site_perl/5.34.0
All that looks fine with no system perl references
The summary:
check that you aren't missing something
check perl -V to see which perl it is and it's default module search path
check environment variables such as PERL5LIB for conflicting values
look in the shebang line for the programs you are running
Do you have everything?
As HÃ¥kon noted, it looks like there are two perl installations interfering with each other. But, also as ikegami said "never seen that" error message. I haven't either, but StackOverflow has seen it.
The entry in [perldiag] is says that the program tried to load the module, failed the first time, and then something tried again:
Attempt to reload %s aborted.
(F) You tried to load a file with "use" or "require" that failed to
compile once already. Perl will not try to compile this file again
unless you delete its entry from %INC. See "require" in perlfunc and
"%INC" in perlvar.
I don't know what keeps it from failing the first time, but you should check with something simple to see if you can load the module:
$ perl -MScalar::Util -e 1
But, it's actually more tricky than this. Maybe that perl can load it, but some other perl can't. And, maybe you have multiple installations of Scalar::Util, but the particular perl and environment and program settings conspire to choose the wrong one.
The environment can tell perl where to look
But, perhaps none of that works.
First, figure out which perl you want to use, and check its settings:
$ perl -V
At the end of the output you should see the interesting environment settings and the default module search path. With a clean session, I don't have any environment variables that contain PERL:
%ENV:
#INC:
/usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0/darwin-2level
/usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0
/usr/local/perls/perl-5.36.0/lib/5.36.0/darwin-2level
/usr/local/perls/perl-5.36.0/lib/5.36.0
However, I can dirty up my environment. I'll set a PERL5LIB value, which prepends directories to the default module search path:
$ export PERL5LIB=/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/5.10.1:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1/darwin-2level:/usr/local/perls/perl-5.10.1/lib/site_perl/5.10.1
Check perl -V again and this interesting thing happens:
Perl lib version (5.10.1) doesn't match executable version (v5.36.0) at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Config.pm line 50.
Compilation failed in require.
BEGIN failed--compilation aborted.
If I try to load Scalar::Util from the command line with -M, which is what I'd expect if you've mixed up the perls:
$ perl -MScalar::Util -e 1
Can't load '/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle' for module List::Util: dlopen(/usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/auto/List/Util/Util.bundle, 0x0001): symbol not found in flat namespace '_PL_sv_no' at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/XSLoader.pm line 73.
at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/List/Util.pm line 23
Compilation failed in require at /usr/local/perls/perl-5.10.1/lib/5.10.1/darwin-2level/Scalar/Util.pm line 23.
Compilation failed in require.
BEGIN failed--compilation aborted.
Programs may be incorrectly adjusting #INC
I don't think this is a problem with cpanm because the world would have complained by now. However, if some program is doing funky things with #INC, it may be adding the wrong things.
I think the likely case for this is a set of vendor module directories they use and that some of those modules are targeted at a particular perl. When you use a different perl, you get the binary mismatch thing.
Programs choose their interpreter
MacOS: two Perl installs: "Dumper.c: loadable library and perl binaries are mismatched" notes that their home-brew cpanm was hardcoded to use the system perl.
But, there's another part involved. You are running some programs, and those programs choose the perl. If you look at their first lines, they either have an absolute path to a perl, like this:
#!/usr/bin/perl
Or they play a trick to find the first perl in your PATH:
#!/usr/bin/env perl
I don't like that second one because I'm never sure which perl it will find first. In Mastering Perl, I have a long example of someone calling a program "perl", dropping it in a user-controlled directory in PATH (or adding that to PATH for you), then acting like its the real perl but turning off taint-checking along the way. Probably not your problem, but when you let the program guess who is going to handle it weird things can happen.
For example, I guess I haven't installed cpanm for v5.36.0 yet:
$ head -1 `which cpanm`
#!/usr/local/perls/perl-5.34.1/bin/perl
When I run just cpanm, it's going to use v5.34.1 and whatever settings I have for that.
I could tell it directly which perl to use, but I then need to tell that perl where to find the program:
$ perl5.36.0 `which cpanm` ...
Likewise, I have older versions of some programs that I address with the version I intend to use (I do a lot of stuff that runs something against many, many perls):
$ head -1 `which cpan5.10.1`
#!/usr/local/perls/perl-5.10.1/bin/perl
$ head -1 `which cpan5.12.5`
#!/usr/local/perls/perl-5.12.5/bin/perl
When you install programs, such as cpanm, the installation adjusts the shebang line for the perl that installed it. Simply running cpanm does not mean that you are installing into the perl you think you are.

Downgrade perl version on mac

First of all am new to MAC.
Am facing similar kind of issue on Mac where its shipped with V5.28.0 but i have to use perl V5.18.2 for my application. Have installed perl 5.18.2 using perlbrew install 5.18.2 and the installation was successful.
Have two questions here
Where are my default version and other version installed ? Is there any command to know them ? Have already tried checking echo $PATH but no use.
How to set the default version to 5.18.2 ?
Regards
AVK
The default installation location is
/usr/bin/perl
But that might not be where it's located on MacOS. You can find out for sure by running the following:
perlbrew off
which perl
(Restarting the terminal will reactivate perlbrew.)
The build you installed is in a directory under the directory returned by the following:
printf -- "%s\n" "${PERLBREW_ROOT:-$HOME/perl5/perlbrew}/perls"
You can modify the PATH so that perl runs the desired build using
perlbrew switch <name> # Changes it for this shell instance and those created later.
perlbrew use <name> # Changes it for this shell instance only.
You can get the names to use from
perlbrew list
See Switching to the system Perl using perlbrew for switching to the system Perl.
Scripts need to have the correct perl specified on their shebang (#!) line. Scripts installed by the standard Perl module installers will have this set correctly, but you'll need to edit the shebang (#!) line of scripts you've installed manually.
Another option (incompatible with perlbrew) is to use plenv. This lets you run different versions of perl for each directory. After installing with brew install plenv, you'd use it like so:
$ plenv install 5.18.2
$ cd project/needing/old/perl
$ echo "5.18.2" > .perl-version
Poof! Running perl in that directory or any of its subdirectories will use 5.18.2.
Note: if you run a perl script with ./script.pl, which has #!/usr/bin/perl, this should continue to use the perl installed at /usr/bin/perl. However, if the shebang line is /usr/bin/env perl, this should switch to the version specified by the .perl-version file.

How can I make a Perl script executable in Windows 64bit?

I am trying to run the perl script through command line but it is not reorganizing the script file ie.
myscript.pl... is not working
but perl myscript.pl is working fine
I have tried the following suggestions but they didn't work either
How do I make my Perl scripts act like normal programs on Windows?
Perl execution from command line question
I am using Active Perl:- Perl 5 , Version 18.
It gives following warnings in both cases.
Using a hash as a reference is deprecated
earlier I installed strawberry perl before installing active perl, is that causing some problem.
The error message
Using a hash as a reference is deprecated
is a Perl message. Your script is being run just fine, but contains an error.
(It is remotely possible that you have two Perl versions installed, and that you configured Windows to use the wrong one. Reconfigure it to use the correct on then, using the guides you already found.)

How to use default path for ActivePerl 5.20 Mac OS X (/usr/bin/perl) instead of /usr/local/ActivePerl...?

I have installed ActivePerl 5.20.2 today on Mac OS X 10.9.5
Checking the version of perl in Terminal (perl -v) I see 5.20.2
So everything seems to be ok. But..
When I start my CGI scripts the script is running under built in perl (which is 5.16) (if using #!/usr/bin/perl).
If I use #!/usr/local/ActivePerl5.20.2/bin/perl then it runs under 5.20.2 that is required.
The question is: is it somehow possible to change the directory for using in my scripts from #!/usr/local/ActivePerl5.20.2/bin/perl to simple and familiar #!/usr/bin/perl keeping running under ActivePerl instead of built in.
I need to override the system's default version with the new ActivePerl.
I would be appreciated for your detailed answers (with name of files and directories where they are located) if ones are to be changed to implement salvation.
Thanks!
The question is: is it somehow possible to change the directory for using in my scripts from #!/usr/local/ActivePerl5.20.2/bin/perl to simple and familiar #!/usr/bin/perl keeping running under ActivePerl instead of built in.
Don't even try. That way lies damnation, not salvation. The ability to specify the specific interpreter that will handle your scripts is an important feature.
Instead, package your CGI script as a simple CPAN module. Then, install it using the familiar
$ /usr/local/ActivePerl5.20.2/bin/perl Makefile.PL
$ make install
routine. The shebang line will be automatically adjusted to reflect the perl that was used to build and install your package.
First, instead of specifying a particular path to your Perl interpreter in your script:
#! /usr/local/ActivePerl5.20.2/bin/perl
or
#! /usr/bin/perl
Specify this:
#! /usr/bin/env perl
This will find the first executable Perl interpreter in your $PATH and then use that to execute your Perl script. This way, instead of having to change your program, you only have to change the $PATH variable.
Next time, take a look at PerlBrew for installing a different version of Perl. PerlBrew will allow you to install multiple versions of Perl all under user control, and let you select which version of Perl you'd like to use.
I also recommend to put /usr/local/bin as the first entry in your $PATH. Then, link the executables you want to run to that directory. You can use something like this to create your links:
for file in $/usr/local/ActivePerl5.20.2/bin/*
do
basename=$(basename $file)
ln -s "$file" "/usr/local/bin/$basename"
done
This way, all programs you want to execute are in the same directory which makes setting $PATH so much easier. I even put /usr/local/bin in before /usr/bin and /bin because I want to be able to override the system's default version.

perl can't find installed modules but CPAN can, plus I can find them. Why can't perl?

I'm using macports supplied perl 5.16.3 installed in /opt/local/bin on my macbook 10.6
jason-danckss-macbook:eg Jason$ which perl
/opt/local/bin/perl
I was testing the demo.pl file that came with AI:Categorizer.pm from metaCPAN. I installed AI:Categorizer via CPAN supplied with macports perl:
tried to run it:
original:
./demo.pl /users/Jason/Desktop/Dropbox/capstone/capstone/notes/HTML/sock
Can't locate AI/Categorizer.pm in #INC (#INC contains: /sw/lib/perl5/5.10.0/darwin-thread-multi-
2level /sw/lib/perl5/5.10.0 /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5
/darwin /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network
/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library
/Perl/Extras/5.10.0 .) at ./demo.pl line 21.
BEGIN failed--compilation aborted at ./demo.pl line 21.
slightly modified with: use lib "/opt/local/lib/perl5/5.16.3"; because that's where the modules are being written when I use CPAN (I use perl -MCPAN -e shell IDK if that matters)
jason-danckss-macbook:eg Jason$ ./demo.pl ../HTML/sock
Can't locate AI/Categorizer.pm in #INC (#INC contains: /opt/local/lib/perl5/5.16.3/darwin-thread-
multi-2level /opt/local/lib/perl5/5.16.3 /sw/lib/perl5/5.10.0/darwin-thread-multi-2level /sw/lib
/perl5/5.10.0 /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5/darwin
/Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System
/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network
/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library
/Perl/Extras/5.10.0 .) at ./demo.pl line 21.
BEGIN failed--compilation aborted at ./demo.pl line 21.
check its in the right spot:
jason-danckss-macbook:eg Jason$ find /opt/local/lib/perl5 -name 'Categorizer.pm'
/opt/local/lib/perl5/site_perl/5.16.3/AI/Categorizer.pm
I even tried to use diagnostic. Neither I nor perl can find diagnostic.pm. CPAN cant find it. I'm guessing it was removed in more recent perl versions?
OK so I have both fink and macports on my computer, along with a default perl installation. the macports version perl is the first perl found in $PATH. I'm OK with it after all its its pretty recent: 5.16.3
I don't know or think reading modules from multiple locations is a bad idea. but IDK. I'd hate to think what kind of gymnastics I might need to do to fix this.
Has anyone encountered this before?
I have just had a look at the AI::Categorizer bundle and the included demo.pl file has a hardcoded shebang of #!/usr/bin/perl so I believe it is trying to use the system perl.
Assuming you haven't already tried changing this line (the first line of demo.pl) to point at /opt/local/bin/perl then I suspect doing so will fix your problem.
You might also consider setting the shebang to /usr/bin/env perl which should use the version of perl from your path. Also have a look at perlbrew which is probably a better way to install non-system versions of Perl.

Resources