Miral
Miral

Reputation: 31

$* is no longer supported as of Perl 5.30

We are moving from an old unix server with perl 5.8.8 to a new server with Perl 5.32. We have a script that starts with following lines:

eval "exec /usr/local/bin/perl -S $0 $*"    
    if $running_under_some_shell;
                        # this emulates #! processing on NIH machines.    
                        # (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;    
                        # process any FOO=bar switches

$[ = 1;                 # set array base to 1
$, = ' ';               # set output field separator
$\ = "\n";              # set output record separator

The script doesn't work. For the line "eval "exec /usr/local/bin/perl -S $0 $*"" we get:

$* is no longer supported as of Perl 5.30 at /usr/local/ccmngr/bin/check_log.pl line 12. 

If I remove the $* from eval line, we get the following for line $[ = 1;:

Assigning non-zero to $[ is no longer possible at /usr/local/ccmngr/bin/check_log.pl line 20.

If anybody has an idea and like to share, it will be great help.

Upvotes: 2

Views: 1591

Answers (3)

zdim
zdim

Reputation: 66924

These two should not have been used for a while.

Related to that use of $*, perlrun for -S explains its convoluted usage and rationale. In short,

Typically this is used to emulate #! startup on platforms that don't support #!.

So I'd first try to just get rid of that line, since reasons for it may be entirely historical, and use the normal #!/path-to-perl; (seems to be #!/usr/local/bin/perl;), or if you needed to trigger the version of Perl that is first in your path (doesn't seem to be the case) use /usr/bin/env. See the linked docs.

As for $[, the perlvar for $[ says

This variable stores the index of the first element in an array, and of the first character in a substring. The default is 0, but you could theoretically set it to 1 ... As of Perl v5.16.0, it is implemented by the arybase module.

However, even as the quote above is from the most recent perldoc, the arybase isn't available anymore, neither as core nor via CPAN. One can always get the package from CPAN (the most recent version appears to be for 5.28) and install it and keep fingers crossed ... but that's not really promising. Instead, Array::Base does exist and work per its synopsis (checked on 5.32).

(I'd really rather recommend to use 0-based arrays in a Perl script but I don't know whether it's feasible to change that in your program.)

More, you may well need to (carefully) rework quite a bit more, jumping from 5.8 to 5.32.


It may be that the compiler is confusing that $* as a (removed) regex variable and complaining about that, since $* there is meant to be used by a csh shell (so perl shouldn't have a problem with it). If true, that may be possible to fix somehow.

But regardless, it's far better to just remove it if it's not anymore needed all these years later.

Upvotes: 6

ikegami
ikegami

Reputation: 386461

Let's look at the following lines first:

eval "exec /usr/local/bin/perl -S $0 $*"    
    if $running_under_some_shell;
                        # this emulates #! processing on NIH machines.    
                        # (remove #! line above if indigestible)

The $* is not intended to be used by Perl. If this program is run by perl, these lines do nothing because $running_under_some_shell is false.

But if it's run by a shell, the first line ends up getting executed, and it's meant to get perl to execute the script. These lines are there to make ./script work on machines that have no shebang (#!) support.

Fix

Unless you're running this script on some weird ancient machine, you can avoid the issue by replacing those lines with

#!/usr/bin/perl

$[ is no longer supported.

  • 5.12 (2010): Assignment to $[ was deprecated.
  • 5.16 (2012): Assignment to $[ was disabled unless use feature 'array_base'; was used.
  • 5.16 (2012): Assignment to $[ now only effects the current lexical scope.
  • 5.28 (2018): The release notes warn that assignment to $[ will be removed in 5.30.
  • 5.30 (2019): Assignment to $[ (and use feature 'array_base';) was removed.

Plenty of warning was given. You need to convert your code to expect 0-based arrays.

In the meantime, here are two workarounds you could use.

Workaround 1

Replace

$[ = 1;

with

use Array::Base +1;

I would consider this a temporary fix. I wouldn't rely on this to keep working.

Workaround 2

Install Perl 5.28 (or earlier, e.g. using perlbrew), and replace

$[ = 1;

with

# ***** WARNING: THIS STOPS WORKING IN PERL 5.30 *****
no warnings qw( deprecated );
use feature qw( array_base );
$[ = 1;
use warnings qw( deprecated );

Again, this is just to buy you time to adjust your program to use 0-based arrays.

Upvotes: 5

Dave Cross
Dave Cross

Reputation: 69314

If you have vital code that is written in Perl, then you shouldn't be running it using the system Perl - as you've seen, this can prevent you from upgrading your operating system.

Instead, you should have your own installation of Perl which is a version known to work with your code. perlbrew is a handy tool for doing this.

(But, yes, you should also look at using code that isn't quite as old as that!)

Upvotes: 1

Related Questions