NAME
Perl500503Syntax::OrDie - Validate that source code is compatible with Perl 5.005_03
VERSION
0.04
SYNOPSIS
# Place at the top of any script you wish to guard:
use Perl500503Syntax::OrDie;
# The remainder of the script is validated automatically.
use strict;
use vars qw($x);
$x = 42;
open(FH, ">output.txt") or die $!; # OK: 2-argument bareword form
print FH "$x\n";
close FH;
mkdir("newdir", 0755); # OK: explicit mode
# Programmatic API (no auto-check, no runtime guards):
use Perl500503Syntax::OrDie ();
my @v = Perl500503Syntax::OrDie::check_source($source_text, 'label.pl');
if (@v) { warn $_ for @v }
Perl500503Syntax::OrDie::check_file('/path/to/script.pl'); # dies on violation
# Command-line (stdin supported):
# perl lib/Perl500503Syntax/OrDie.pm myscript.pl
# perl lib/Perl500503Syntax/OrDie.pm script1.pl script2.pl ...
# perl lib/Perl500503Syntax/OrDie.pm -
DESCRIPTION
Perl500503Syntax::OrDie helps authors who target Perl 5.005_03 compatibility detect incompatible constructs before deploying code to legacy systems.
When loaded with use Perl500503Syntax::OrDie;, the module:
Uses
caller()to locate the calling source file.Reads that file and runs a two-stage scan. Stage 1: the source is masked (comments, string literals, and regex literals replaced with
Xwhile preserving newlines) and scanned against@BLACKLIST. Stage 2: the content of each regex literal (m//,s///,qr//,//) is scanned against@REGEX_BLACKLIST.Dies with file name and line number on any violation.
Installs
CORE::GLOBAL::overrides that enforce correct runtime behaviour foropen()andmkdir().
String and regex contents are intentionally not inspected: a string literal may freely contain any text (such as "say" or "%v") without triggering a violation, because those are runtime values, not syntax constructs.
No source-filter infrastructure (Filter::Util::Call, etc.) is required or used. The module works on every Perl from 5.005_03 through the current release.
PROGRAMMATIC API
check_source($source, $label)-
Scans
$source(a string) and returns a list of violation strings. Returns an empty list when no violations are found. Does notdieautomatically; the caller decides what to do with the list. String and regex contents are not inspected; only source-level syntax constructs are flagged.my @v = Perl500503Syntax::OrDie::check_source($src, 'foo.pl'); if (@v) { warn $_ for @v } check_file($path)-
Reads
$pathand callscheck_source. Dies with the violation list if any violations are found; returns normally otherwise.
CHECKED CONSTRUCTS
Static checks (compile time, via source scan)
ourdeclaration -- Perl 5.63-argument
open()-- Perl 5.6use utf8-- Perl 5.6use VERSIONwhere VERSION >= 5.6use vVERSIONwhere VERSION >= v5.6\x{HHHH}Unicode escape -- Perl 5.6 (in a regex and in an interpolating string literal alike; a single-quoted string performs no escape processing and is not scanned)\N{name}named character escape -- Perl 5.6 (same scanning rule as\x{HHHH})Match-position arrays
@+/@-and$+[N]/$-[N]-- Perl 5.6CHECK/INITphase blocks -- Perl 5.6v-string notation (
v1.2.3) -- Perl 5.6$^Vversion object -- Perl 5.6:lvaluesubroutine attribute -- Perl 5.6Typeglob component access
*name{SLOT}-- Perl 5.6Lexical filehandle or directory handle -- Perl 5.6 (
open(my $fh, ...),opendir,sysopen,pipe,socket,socketpair,accept. Only themyspelling is reported:open($fh, ...)against a lexical that already holds a glob is valid Perl 5.005_03 and cannot be told apart from the invalid case.)binmode()with a LAYER argument -- Perl 5.6 (a question of arity: Perl 5.005_03binmodetakes the filehandle alone, whatever the layer string would have said)use warnings/no warningswithout the$INC{'warnings.pm'}stub -- Perl 5.6 (the guarded idiom,BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 }ahead of the statement, is a no-op on Perl 5.005_03 and is treated as compatible, exactly as the empty-import form ofuse featureis. The stub is recognised only where it is live code, so the idiom quoted in a comment or in POD does not excuse an unguarded statement.)use encoding-- Perl 5.8use constant { HASH }multi-constant form -- Perl 5.8defined-or assignment operator
//=-- Perl 5.10say-- Perl 5.10 (->say()method calls andsay =>hash keys excluded)state variable-- Perl 5.10given/when-- Perl 5.10Smart-match
~~-- Perl 5.10use feature-- Perl 5.10 (the empty-import formuse feature ()is a no-op on every Perl version and is treated as compatible)Defined-or operator
//(standalone) -- Perl 5.10UNITCHECKphase block -- Perl 5.10${^MATCH}/${^PREMATCH}/${^POSTMATCH}-- Perl 5.10package NAME VERSION-- Perl 5.12Yada-yada
...-- Perl 5.12s///rortr///rnon-destructive flag -- Perl 5.14__SUB__token -- Perl 5.16my sub/state sublexical subroutine -- Perl 5.18Subroutine signatures -- Perl 5.20
Postfix dereference
$ref->@*-- Perl 5.20%hash{LIST}/%array[LIST]key/value slices -- Perl 5.20&.|.^.~.string bitwise operators -- Perl 5.22Reference aliasing in
foreach-- Perl 5.22<<>>double-diamond operator -- Perl 5.22/nnon-capturing regex flag -- Perl 5.22<<~indented heredoc -- Perl 5.26isainfix operator -- Perl 5.32 (->isa()method calls andisa()function calls excluded)tryblock -- Perl 5.34use builtin-- Perl 5.36for my ($a,$b)paired iteration -- Perl 5.36classkeyword -- Perl 5.38^^/^^=high-precedence logical XOR -- Perl 5.40__CLASS__keyword -- Perl 5.40any BLOCK LIST/all BLOCK LISTkeyword operators -- Perl 5.42 (suppressed whenList::Utilimportsany/all)my methodlexical method declaration -- Perl 5.42->&namelexical method call -- Perl 5.42Possessive quantifiers
a++/a*+/a?+in code -- Perl 5.10\p{}\P{}Unicode property escapes in regex -- Perl 5.6\K(keep) in regex -- Perl 5.10Named capture
(?<name>...)and\k<name>-- Perl 5.10Branch reset
(?|...)in regex -- Perl 5.10Backtrack control verbs
(*VERB)in regex -- Perl 5.10\h/\H/\v/\V/\Rregex escapes -- Perl 5.10Variable-length lookbehind in regex -- Perl 5.30/5.38
Possessive quantifiers in regex -- Perl 5.10
Recursive patterns
(?PARNO)/(?&name)/(?R)-- Perl 5.10\g{N}relative/absolute backreference -- Perl 5.10
String checks (body of interpolating string literals)
What a string says is not inspected: a string literal may contain any text, including PerlIO layer names or sprintf format flags, and remains valid Perl 5.005_03 syntax. How it is spelled is another matter, and the escape sequences below are syntax:
\x{HHHH}Unicode escape -- Perl 5.6\N{name}named character escape -- Perl 5.6
Scanned in "...", qq//, qx//, `...`, an unquoted or double-quoted heredoc body, and the replacement half of s/// unless it is single-quote delimited. '...', q//, qw// and <<'WORD' perform no escape processing, so the same characters there are an ordinary backslash followed by text and are not reported.
RAW checks
None.
Runtime checks (via CORE::GLOBAL:: overrides)
open()with 3 or more arguments -- Perl 5.6open()with a reference as the mode argumentmkdir()without an explicit mode argument -- Perl 5.6
DIAGNOSTICS
- Perl500503Syntax::OrDie: VIOLATION at <file> line <N>: <description>
-
A construct not available in Perl 5.005_03 was detected in the source file.
- Perl500503Syntax::OrDie: RUNTIME VIOLATION at <file> line <N>: <description>
-
A built-in function was called at runtime in a manner not supported by Perl 5.005_03.
- Perl500503Syntax::OrDie: cannot open '<file>': <reason>
-
The calling source file could not be opened for reading.
COMPATIBILITY
This module itself is written to run on every Perl from 5.005_03 through the current release:
use varsinstead ofour$^Wsemantics; nouse warningswithout guard2-argument
open(BAREWORD, $path)with bareword filehandlesNo syntax or function introduced after 5.005_03
LIMITATIONS
The source masker handles the most common quoting forms but is not a full Perl lexer. Unusual constructs may occasionally yield false positives or negatives.
Dynamically generated code (e.g.
eval "our \$x = 1") is not checked statically.CORE::GLOBAL::overrides affect the entire interpreter process. Do not use this module in production deployments.Regex violations are reported with the line number of the opening delimiter of the regex, not the line within the regex body. A violation inside a heredoc body is reported with the line number of the body, not of the
<<operator.
SEE ALSO
AUTHOR
INABA Hitoshi <ina.cpan@gmail.com>
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.