perlperl5.10perl5.8

Can I make sure Perl code written on 5.10+ will run on 5.8?


Some of the new features of Perl 5.10 and 5.12, such as "say", are defined as features, that you can enable or disallow explicitly using the "feature" pragma. But other additions, like the named capture groups of regexes, are implicit.

When I write Perl using a 5.10+ interpreter, but want it to also run on 5.8, can I make Perl complain about using anything that's not in 5.8? Obviously, it is good practice to test your code on all major versions you intend it to run on, but it'd still be nice to have Perl warn me automatically.


Solution

  • When I want to ensure that a program will run under particular versions of perl, I test it under that version of perl. A feature of my release application tests under multiple perls before it actually uploads.

    This requires that you have a proper test suite and write enough tests. It's easy to maintain several separate perl installations at the same time, too, as I show in Effective Perl Programming.

    Test::MinimumVersion almost sounds like it might work, but it has several limitations. It only looks at the file you give it (so it will not check anything you load), and I don't think it actually looks inside regex patterns. Each of these report that the minimum version is 5.004, which is not true for any of them:

    #!perl
    
    use Perl::MinimumVersion;
    
    my $p_flag = <<'SOURCE';
    '123' =~ m/[123]/p; # 5.10 feature
    SOURCE
    
    my $named_capture = <<'SOURCE';
    '123' =~ m/(?<num>[123])/; # 5.10 feature
    SOURCE
    
    my $r_line_ending = <<'SOURCE';
    '123' =~ m/[123]\R/p; # 5.12 feature
    SOURCE
    
    my $say = <<'SOURCE';
    say 'Hello';
    SOURCE
    
    my $smart_match = <<'SOURCE';
    $boolean = '123' ~~ @array;
    SOURCE
    
    my $given = <<'SOURCE';
    given( $foo ) {
        when( /123/ ) { say 'Hello' }
        };
    
    SOURCE
    
    foreach my $source ( $p_flag, $named_capture, $r_line_ending, $say, $smart_match, $given ) {
        print "----Source---\n$source\n-----";
        my $version = Perl::MinimumVersion->new( \$source  )->minimum_version;
        print "Min version is $version\n";
        }
    

    Part of the reason Perl::MinimumVersion works is because it looks for hints that the source gives it already, such as use 5.010, and use feature so on. However, that's not the only way to enable features. And, as you'll note, it misses things like the /p flag, at least until someone adds a check for that. However, you'll always be chasing things like that with a PPI solution.

    It's easier just to compile it, run the tests, and find out.