May I use Strawberry Perl and ActiveState Perl simultaneously on one computer? - perl

I used to delete my ActivePerl once, and all the installed modules were lost. So now I am very careful with this kind of issue. Due to some reason, I want to use Strawberry Perl now, while keeping ActiveState's ActivePerl in use.
Will this cause compatibility issues? Is it advisable?

This will not be a problem as both the Perl implementations will look at different directories for modules. That is, the #INC entries will be different.

I keep both ActivePerl and Strawberry Perl installed on my Windows 7 Pro instance. My PATH variable order decides my Perl preference. E.g, for using ActivePerl I set my PATH to something like this:
C:\Perl64\bin;C:\strawberry\perl\bin
You can always override this in your script using shebang:
#!C:\strawberry\perl\bin\perl

You could use two (many) different Perl versions at once.
Set your PATH variable to include your primary Perl path (path to perl.exe) to be sure that you are running the correct Perl when you start a program with perl script.pl.
You could use Perlbrew (or other modules) to help keeping multiple Perl installations on your computer.
It is available on Windows: http://code.activestate.com/ppm/App-perlbrew/

I found another solution for this. You could embed your Perl code into a Windows batch file. This way you could set environment variables before executing your Perl script or include your module path.
#echo off
cd %TEMP%
set perl_bindir=C:\strawberry\perl\bin
set module_dir=C:\my_perl_modules
set path=%perl_bindir%;%path%
echo Launching %0 perl script
%perl_bindir%\perl.exe -I %module_dir% -x -S %0 %*
goto endofperl
#!perl -w
use strict;
print "Hello World\n";
__END__
:endofperl

Related

Cygwin: Perl script $ENV{PATH} call returns unix path. How do I change it?

I am calling a Perl script from cygwin. The issue that I am having is that when it calls $ENV{PATH}, the path is receives is a unix path. How do I change my shell so it returns a DOS path?
Cygwin is a Unix-emulation environment for Windows. It wouldn't work unless $PATH was a Unix-style path.
If you want perl to give you a DOS path, use a DOS-compatible Perl, like Strawberry Perl. You can even run Strawberry Perl (or whatever Windows-build of perl you use) from Cygwin if you want to.
It has nothing to do with the shell, so changing shell won't help, and there's nothing you can change in the shell to help.
>echo %PATH% & perl -E"say $ENV{PATH}"
c:\progs\cygwin\bin;...;C:\Windows\system32;...
/usr/bin:...:/cygdrive/c/Windows/system32:...
The purpose of cygwin is to allow unix program to be compiled on a Windows machine with as little changes as possible, which means the system calls must behave as if the program was executing on a unix machine, which means the PATH must look like a unix path.
If you had used a Windows build of Perl (such as ActivePerl or Strawberry Perl), you wouldn't have this problem.
If you wish to continue using a Cygwin build of Perl, you could use the Cygwin tool cygpath to convert the paths for you.
$ perl -E'
my $cmd = q{IFS=: ; cygpath -w $PATH};
chomp( my #paths = `$cmd` );
say for #paths;
'
C:\progs\cygwin\home\ikegami\usr\perlbrew\bin
.
C:\progs\cygwin\home\ikegami\bin
C:\progs\cygwin\usr\local\bin
C:\progs\cygwin\bin
C:\progs\perl5163-ap1603\site\bin
C:\progs\perl5163-ap1603\bin
C:\bin
C:\Windows\system32
C:\Windows
...
You can use cygpath and call bash with: (Looks like you have to set IFS.)
` IFS=:; cygpath --windows \$PATH`
Or unsetting IFS.
`IFS=;cygpath --windows --path \$PATH`
Or you could just do it with a few simple rules.
map {
# turn cygdrives to drive letter + colon
s!^/cygdrive/(\w)/!\U$1:!;
# locate the cygwin relative paths to whatever it is on your system.
s!^/!$CYGWIN_HOME/!;
$_ = qq("$_") if m/[() ]/; # quote paths where necessary
# You don't really need to switch the slashes for perl, Java
# a lot of other multi-platform tools.
s!/!\\!g;
} split /:/, $ENV{PATH}
;
Note that you might have to expand the character set in the match expression.
I hope this helps, although maybe a bit late :)
Copy the PATH to a Cygwin-unrecognised variable and use that instead:
set MYPATH=%PATH%
perl -e 'print join("\n",split(";",$ENV{MYPATH}),"\n")'

Perl pp utility locale problems

i am trying to use pp utility from PAR package to create an exe file of my Perl program on windows
eg
pp -o script.exe script.pl
The command runs ok, but when i try to run the exe, it gives me
The locale codeset (cp1252) isn't one that perl can decode, stopped at Encode/Locale.pm line 94. Compilation failed in require at LWP/UserAgent.pm line 1000.
What could be the problem? I have a list of modules being used in the script, these include, Cwd, LWP::Simple, LWP::Useragent , Win32::OLE.
enviroment:
1) windows vista
2) Activestate Perl 5.16
3) did not manage to install PAR::Packager successfully, unless i use "force" install, which manage to install.
thanks
Encode::Locale finds the modules it needs to decode various encodings in a way that pp can't discover automatically. You'll need to tell pp which additional modules are required.
This should do the trick:
pp -m Encode::Byte -o script.exe script.pl

What should be the first line of a Perl test (.t) script?

I was looking through my CPAN distributions and realized that I had various inconsistent things at the top of my .t scripts, based on where I'd cargo-culted them from. This of course offends me.
So, what's the "best" first line of a Perl test (.t) script? A non-scientific survey of my .cpanm sources showed me:
3429 use strict;
3211 #!/usr/bin/perl
1344 #!/usr/bin/env perl
937 #!perl
909 #!/usr/bin/perl -w
801 #!perl -w
596
539 #!perl -T
Related to What should I use for a Perl script's shebang line?, but here I'm wondering if the shebang is necessary/useful at all, if tests are always expected to be called from prove.
use strict; should be in EVERY Perl program (as well as use warnings; and probably a few others (depending who you talk to). It doesn't have to be the first line.
The rest of the stuff you present are merely multiple versions of the shebang. On Unix and Unix based systems, the shebang is used to tell the interpreter to use. If the shebang isn't there, the current shell will be used. (That is, if your shell supports the shebang1.).
If you are on a Windows system, that shebang line is useless. Windows uses the suffix of the file to figure out how to execute the file.
The question is whether you really even need a shebang line in scripts that you run through a test harness. I don't normally execute these test scripts individually, so there may not really be a need for the shebang at all. In the rare event you do want to execute one of these scripts, you could always run them as an argument to the perl command itself. The same is true with Perl modules.
So, why the shebang? Mainly habit. I put one too on my test scripts and on my modules. If nothing else, it makes it easy to run modules and test scripts independently for testing purposes. Plus, the shebang lets people know this is a Perl script and not a shell script or a Python script.
There's a little issue with the shebang though, and that has to do with portability. If I put #! /usr/bin/perl on my first line, and the Perl interpreter is in #! /usr/local/bin/perl, I'll get an error. Thus, many of the shebangs reflect the location of the Perl interpreter for that developer.
There's also another issue: I use Perlbrew which allows me to install multiple versions of Perl. The version of Perl I currently have in my shell is at /Users/David/perl5/perlbrew/perls/perl-5.18.0/bin/perl. That's not good if I pass that program to another user on another system. Or, if I decide I want to test my Perl script under 5.10.
The #! perl variant is an attempt to solve this. On SunOS (I believe), this would execute the Perl that's in your $PATH (since it could be /usr/local/bin/perl or /usr/share/bin/perl or /usr/bin/perl depending upon the system). However, this does not work on most Unix boxes. For example, on my Mac, I would get a bad interpreter error.
I use #! /usr/bin/env perl. The env program takes the argument perl, sees where perl is on my $PATH, and then executes the full path of wherever Perl happens to be on my $PATH. This is the most universal way to do the shebang and the way I recommend. It allows those of use to use Perlbrew without problem.
Note, I said almost universal, and not universal. On almost all systems, env is located in /usr/bin, but there apparently some systems out there where env is either on /bin, located elsewhere, or not on the system at all.
The -w turns on warnings when executing Perl. Before Perl 5.6, you used this to turn on warnings. After Perl 5.6, you can use the more flexible use warnings; and the -w is now considered deprecated2. Programs may use it because they were originally written pre 5.6, and never modified or the developer simply did it out of habit.
The -T has to do with taint mode. Taint mode is normally used for CGI scripting. Basically, in Taint mode, data from outside a program is considered tainted and cannot be used until untainted. Taint mode also affects #INC and PERLLIB.
The real answer is that there is no set answer. I'd put #! /usr/bin/env perl as my first line out of habit -- even if I never expect to execute that file from a Unix command line. There's no real need for it for these types of scripts that are almost always executed as part of the install and not directly from the command line. What you see is really the result of 30 years of Perl habits and cruft.
1. Your shell supports the shebang unless you're using a 30 year old version of the Bourne shell or a very old version of the C shell.
2. I actually don't know if -w has ever been officially deprecated, but there's no reason to use it.
.t files are still regular Perl script. Use whatever you need for this particular script on first line.

invoking perl scripts

I have perl scripts starting with #!/usr/bin/perl or #!/usr/bin/env perl
First, what does the second version mean?
Second, I use Ubuntu. All the scripts are set as executables. When I try to run a script by simply invoking it's name (e.g. ./script.pl) I get : No such file or directory. when I invoke by perl ./script.pl it runs fine.
Why?
The #!/usr/bin/env perl uses the standard POSIX tool env to work around the "problem" that UNIX doesn't support relative paths in shebang lines (AFAIK). The env tool can be used to start a program (in this case perl) after modifying environment variables. In this case, no variables are modified and env then searches the PATH for Perl and runs it. Thus a script with that particular shebang line will work even when Perl is not installed in /usr/bin but in some other path (which must be in the PATH variable).
Then, you problem with ./script.pl not working: you said it has the executable bit(s) set, like with chmod +x script.pl ? But does it also start with a shebang (#!) line ? That is, the very first two bytes must be #! and it must be followed by a file path (to perl). That is necessary to tell the kernel with which program to run this script. If you have done so, is the path correct ? You want to try the #!/usr/bin/env perl variant ;-)
Using #!/usr/bin/env perl gets around the problem of perl not necessarily being in /usr/bin on every system; it's just there to make the script more portable
On a related note, for your second problem, is there a /usr/bin/perl and/or /usr/bin/env? If not, that would explain why running the scripts directly doesn't work; the shebang isn't handled if you run the script as an argument to perl

How do I set up Strawberry Perl in MSYS?

I have Strawberry Perl and have msys Perl 5.6 removed.
Now perl will invoke Strawberry (due to PATH env) but how do I map the perl command in .pl or other Perl script files which have #!/bin/perl or #!/usr/bin/perl shebang lines?
I was thinking of making a hardlink to perl.exe in msys/bin or merge the whole Strawberry inside the msys directory, but I'm not sure.
The solution is to create a symlink to the Strawberry Perl executable from within MSYS Tip of the hat to smaudet for his input:
First, remove or rename the Perl executables that the MSYS installation came with, if any (which the OP has already done); e.g.:
mv /usr/bin/perl /usr/bin/perl.msys
mv /usr/bin/cpan /usr/bin/cpan.msys
Then create a symlink to Strawberry Perl's executable in its place:
ln -s /c/strawberry/perl/bin/perl.exe /usr/bin/perl
# Unfortunately, doing the same for `cpan` doesn't work directly, because
# Strawberry Perl's `cpan` executable is a *batch* file, `cpan.bat`, which
# cannot be directly invoked from MSYS.
# To invoke it from MSYS (assuming it is in the %PATH%):
# cmd /c 'cpan.bat ...'
# With an explicit path:
# cmd /c 'c:\strawberry\perl\bin\cpan.bat ...'
#
# Here's how to create a stub script that still allows invocation as
# `cpan`:
echo 'cmd /c "C:\strawberry\perl\bin\cpan.bat $*"'>/usr/bin/cpan && chmod +x /usr/bin/cpan
Once the /usr/bin/perl symlink is in place, existing scripts with shebang lines #!/usr/bin/perl and #!/bin/perl will work again (the latter also works, because /bin and /usr/bin are effectively the same location in MSYS).
Note that scripts written with the more flexible shebang line #!/usr/bin/env perl do not need this, because env will directly find Strawberry Perl's perl.exe in the path.
Some background:
Unix-emulation environments such as MSYS and Cygwin do not respect Windows' %PATHEXT% variable to determine what executable to invoke a (non-binary) file with. In other words: filename extensions have no meaning with respect to execution there.
Instead, they solely go by whether the file has a shebang line:
If there is one, the executable specified in the shebang line is used.
If there is none, the default (POSIX-like) shell /bin/sh is used.
Thus, trying to invoke *.bat or *.cmd files directly fails, because they don't have a Unix shebang line and are therefore executed by /bin/sh rather than cmd.exe.
Unlike in Windows, this also works with (executable) files that have no filename extension at all.
this works beautifully on the windows side of the computer, on the MSYS side you may need to
check the PATH environment variable and fix to include the strawberry perl access path
check the scripts for complete path in the shebang line (#!/usr/bin/perl).
Those paths that are absolute in msys are in fact relative to the msys install directory in windows.
you may need to "plug" your strawberry perl install to match or change the #! line
in the latter case my recommendation would be to use something like: #!env perl that checks the environment for the perl interpreter and alleviate the burden of dealing with /cygdrive/c/my/windows/path/not/visible/from/msys/otherwise
The correct shebang would be, eg. #!"C:/strawberry/perl/bin/perl.exe". However, you might prefer to run scripts explicitly with Perl rather than rely on the shebang, eg. perl script.pl or perl "C:\strawberry\perl\bin\cpan"
Note that Strawberry Perl doesn't get the shebang right for its own scripts, such as cpan and perldoc . Bug reported at https://rt.cpan.org/Public/Bug/Display.html?id=82837