The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Syntax::Construct - Explicitly state which non-feature constructs are used in the code.

VERSION

Version 1.038

SYNOPSIS

For some new syntactic constructs, there is the feature pragma. For the rest, there is Syntax::Construct.

use Syntax::Construct qw( // ... /r );

my $x = shift // 'default';
my $y = $x =~ s/de(fault)/$1/r;
if ($y =~ /^fault/) {
    ...
}

There are two subroutines (not exported) which you can use to query the lists of constructs programmatically: introduced and removed (see below).

my @constructs = Syntax::Construct::introduced();
say "$_ was introduced in ",
    Syntax::Construct::introduced($_) for @constructs;

DESCRIPTION

This module provides a simple way of specifying syntactic constructs that are not implemented via the feature pragma, but are still not compatible with older versions of Perl.

It's the programmer's responsibility to track the constructs and list them (but see Perl::MinimumVersion on how to extract the information from existing code).

Using use Syntax::Construct qw( // ); doesn't really change anything if you're running Perl 5.010+, but it gives much better error messages in older versions:

Unsupported construct //

instead of

Search pattern not terminated

Three groups of people can benefit from the module:

  1. The authors of the module using Syntax::Construct win, as they have all the constructs in one place (i.e. Syntax::Construct's documentation) and they don't waste their time searching through perldeltas and other places.

  2. Users of their modules win as they get meaningful error messages telling them which Perl version they need to upgrade to.

  3. The programmer they hired to work around the problem wins as they know what constructs to replace in the code to make it run in the ancient version.

Good Practice

Some programmers just use all the non-features their current Perl version provides without any notice. This leads to weird error messages in older Perl versions.

Some other programmers will place use 5.022; towards the top of the script, even if the only non-feature they use is the // operator available in 5.010 already. This prevents users of older versions of Perl to run the script, even if it would otherwise be easily possible.

The kindest programmers will add use 5.010; # // towards the top of the script. But it means they have to remember or find out what version introduced the non-feature they use.

Syntax::Construct liberates you from the need to remember all the non-features together with Perl versions that introduced them. It makes it easier for users of older Perl versions to migrate your code to their system. And finally, it improves the error messages they get.

Similarly, it's a good practice to keep specifying use feature qw{ postderef }; even if it's a no-op since 5.024: it makes your script available for people running older Perl versions. The same applies to use charnames in 5.016 and later, etc.

EXPORT

Nothing. Using Syntax::Construct with no parameters is an error, giving it an empty list is a no-op (but you can then access the introduced and removed subroutines).

introduced

Without arguments, returns a list of all the supported constructs. With an argument, returns the version in which the given construct was introduced.

removed

Same as introduced, but for removed constructs (e.g. auto-deref in 5.024).

RECOGNISED CONSTRUCTS

5.008001

s-utf8-delimiters-hack

See "s-utf8-delimiters". The hack doesn't seem to work in 5.008 and older. Removed in 5.020.

5.010

recursive-sort

"Recursive sort subs" in perl5100delta.

//

"Defined-or operator" in perl5100delta or "Logical Defined-Or" in perlop.

Alias: defined-or

?PARNO

"Recursive Patterns" under "Regular expressions" in perl5100delta or "(?PARNO) (?-PARNO) (?+PARNO) (?R) (?0)" in perlre.

Alias: regex-recursive-subpattern

?<>

"Named Capture Buffers" under "Regular expressions" in perl5100delta or "(?<NAME>pattern)" in perlre.

Alias: regex-named-capture-group

?|

Not mentioned in any Delta. See (?|pattern) in "Extended Patterns" in perlre.

Alias: regex-reset-branch

quant+

"Possessive Quantifiers" under "Regular expressions" in perl5100delta or "Quantifiers" in perlre.

Aliases: regex-possessive-quantifier regex-possessive-match

regex-verbs

"Backtracking control verbs" under "Regular expressions" in perl5100delta or "Special Backtracking Control Verbs" in perlre.

\K

"\K escape" under "Regular expressions" in perl5100delta or "Look-Around Assertions" in perlre.

Alias: regex-keep-left

\R \v \h

Covers \V and \H, too. See "Vertical and horizontal whitespace, and linebreak" under "Regular expressions" in perl5100delta or "Misc" in perlrebackslash.

Aliases: \H \V regex-generic-linebreak regex-horizontal-whitespace regex-vertical-whitespace

\gN

"Relative backreferences" under "Regular expressions" in perl5100delta or "Capture groups" in perlre.

Alias: regex-relative-backreference

readline()

"Default argument for readline()" in perl5100delta.

Alias: readline-argv

stack-file-test

"Stacked filetest operators" in perl5100delta.

/p

/p (preserve) modifier and ${^PREMATCH}, ${^MATCH} and ${^POSTMATCH} variables. Not mentioned in any Delta. See "Variables related to regular expressions" in perlvar.

Alias: regex-preserve-match-captures

lexical-$_

"Lexical $_" in perl5100delta. Removed in 5.024.

Alias: lexical-default-variable

pack<

See "Byte-order-modifiers-for-pack()-and-unpack()" in perl5100delta

Alias: pack-byte-order-modifiers

5.012

package-version

"New package NAME VERSION syntax" in perl5120delta

...

"The ... operator" in perl5120delta or "The Ellipsis Statement" in perlsyn

Aliases: yada-yada triple-dot statement-ellipsis

each-array

"each, keys, values are now more flexible" in perl5120delta

keys-array

"each, keys, values are now more flexible" in perl5120delta

values-array

"each, keys, values are now more flexible" in perl5120delta

delete-local

"delete local" in perl5120delta

length-undef

See the ninth bullet in "Other potentially incompatible changes" in perl5120delta.

\N

"\N experimental regex escape" in perl5120delta.

Alias: regex-non-newline

while-readdir

readdir in a while-loop condition populates $_. Not mentioned in any delta, but see readdir in perlfunc.

5.014

?^

"Regular Expressions" in perl5140delta.

Alias: regex-use-default-modifiers

/r

"Regular Expressions" in perl5140delta and "Modifiers" in perlre.

Aliases: non-destructive-subst non-destructive-substitution

/d

"Regular Expressions" in perl5140delta and "Modifiers" in perlre.

Alias: regex-compile-as-default

/l

"Regular Expressions" in perl5140delta and "Modifiers" in perlre.

Alias: regex-compile-as-locale

/u

"Regular Expressions" in perl5140delta and "Modifiers" in perlre.

Aliases: regex-unicode-strings regex-compile-as-unicode-strings

/a

"Regular Expressions" in perl5140delta and "Modifiers" in perlre.

Alias: regex-restrict-ascii-range

auto-deref

"Array and hash container functions accept references" in perl5140delta. See also push, pop, shift, unshift, splice, keys, values, and each in perlfunc. Removed in 5.024.

^GLOBAL_PHASE

See New global variable ${^GLOBAL_PHASE} under "Other Enhancements" in perl5140delta.

Alias: global-phase

\o

"Regular Expressions" in perl5140delta.

Alias: octal-escape

package-block

See package block syntax under "Syntactical Enhancements" in perl5140delta.

srand-return

See srand() now returns the seed under "Other Enhancements" in perl5140delta.

prototype+

See "Single-term-prototype" in perl5140delta.

5.016

charnames

See "use charnames is no longer needed for \N{name}" in perl5160delta.

5.018

computed-labels

"Computed Labels" in perl5180delta

while-each

See in "Selected Bug Fixes" in perl5180delta or each in perlfunc.

method-on-any-string

See [perl #105922] in "Selected Bug Fixes" in perl5180delta.

split-space

See "split's first argument is more consistently interpreted" in perl5180delta.

5.020

attr-prototype

"subs now take a prototype attribute" in perl5200delta

Alias: attribute-prototype

drand48

"rand now uses a consistent random number generator" in perl5200delta. Note that on OpenBSD, Perl 5.020+ uses the system's own drand48 unless seeded.

%slice

"New slice syntax" in perl5200delta

Alias: hash-slice

unicode6.3

"Unicode 6.3 now supported" in perl5200delta

Alias: unicode-6.3

\p{Unicode}

See New \p{Unicode} regular expression pattern property in "Core Enhancements" in perl5200delta.

Alias: regex-property-unicode

utf8-locale

See use locale now works on UTF-8 locales in "Core Enhancements" in perl5200delta.

s-utf8-delimiters

See "Regular Expressions" in perl5200delta: in older Perl versions, a hack around was possible: to specify the delimiter twice in substitution. Use /s-utf8-delimiters-hack if your code uses it.

Alias: wide-char-delimiters

5.022

<<>>

"New double-diamond operator" in perl5220delta

Aliases: double-diamond operator-double-diamond

\b{}

"New \b boundaries in regular expressions" in perl5220delta

Aliases: regex-unicode-grapheme-cluster-boundary regex-unicode-boundary regex-unicode-word-boundary regex-unicode-sentence-boundary regex-unicode-line-break-boundary \b{sb} \b{wb} \b{gcb}

/n

"Non-Capturing Regular Expression Flag" in perl5220delta

Alias: regex-non-capturing

unicode7.0

See Unicode 7.0 (with correction) is now supported in "Core Enhancements" in perl5220delta.

Alias: unicode-7.0

attr-const

"New :const subroutine attribute" in perl5220delta

Alias: attribute-const

fileno-dir

"fileno now works on directory handles" in perl5220delta

()x=

"Assignment to list repetition" in perl5220delta

Alias: list-repetition-assignment

hexfloat

"Floating point parsing has been improved" in perl5220delta

Alias: hexadecimal-floating-numbers

chr-inf

"Packing infinity or not-a-number into a character is now fatal" in perl5220delta

Alias: pack-inf

empty-slice

"List slices returning empty lists" in perl5220delta

/x-unicode

See qr/foo/x now ignores all Unicode pattern white space in "Incompatible Changes" in perl5220delta.

Aliases: regex-x-unicode regex-x-handles-unicode

5.024

unicode8.0

"Unicode 8.0 is now supported" in perl5240delta.

Alias: unicode-8.0

\b{lb}

"New \b{lb} boundary in regular expressions" in perl5240delta.

sprintf-reorder

"printf and sprintf now allow reordered precision arguments" in perl5240delta.

Aliases: printf-precision-argument-reorder sprintf-precision-argument-reorder

5.026

<<~

"Indented Here documents" in perl5260delta.

Alias: heredoc-indent

/xx

"New-regular-expression-modifier-/xx" in perl5260delta.

Alias: regex-xx

^CAPTURE

See @{^CAPTURE}, %{^CAPTURE}, and %{^CAPTURE_ALL} in perl5260delta.

Alias: capture-variable

unicode9.0

"Unicode 9.0 is now supported" in perl5260delta.

Alias: unicode-9.0

unicode-scx

See "Use of \p{script} uses the improved Script_Extensions property" in perl5260delta.

scalar%

See "scalar(%hash) return signature changed" in perl5260delta. Specifying this construct means the 5.026+ behaviour, i.e. scalar %hash returns the number of keys.

Alias: scalar-hash

5.028

delete%

See "delete-on-key/value-hash-slices" in perl5280delta.

Alias: hash-delete-slice

unicode10.0

See "Unicode 10.0 is supported" in perl5280delta.

Alias: unicode-10.0

state@=

See "Initialisation-of-aggregate-state-variables" in perl5280delta.

Aliases: state-array state-hash list-context-state

5.030

unicode12.1

"Unicode 12.1 is supported" in perl5300delta

Alias: unicode-12.1

uniprop_wildcards

"Wildcards in Unicode property value specifications are now partially supported" in perl5300delta

qr'N

"qr'\N{name}' is now supported" in perl5300delta

Alias: named-char-in-single-quoted-regex

turkic-casing

See "Turkic UTF-8 locales are now seamlessly supported" in perl5300delta. Beware: the actual behaviour depends on the operating system's locale support. E.g. FreeBSD, DragonFly, and Solaris are known not to support it.

^RE_COMPILE_RECURSION_LIMIT

Not mentioned in any Delta. See "${^RE_COMPILE_RECURSION_LIMIT}" in perlvar.

Alias: re-compile-recursion-limit

5.032

unicode13.0

"Unicode 13.0 is supported" in perl5320delta

Alias: unicode-13.0

chained-comparisons

"Chained comparisons capability" in perl5320delta

unicode-identifier-status

"New Unicode properties Identifier_Status and Identifier_Type supported" in perl5320delta

Alias: unicode-identifier-type

unicode-name-property

It is now possible to write \p{Name=...} in perl5320delta

5.034

{,n}

"qr/{,n}/ is now accepted" in perl5340delta

Alias: empty-left-quantifier

0o

"New octal syntax 0oddddd" in perl5340delta

Alias: octal-literals

blanks-in-curlies

"Blanks freely allowed within but adjacent to curly braces" in perl5340delta

5.036

unicode14.0

"Unicode 14.0 is supported" in perl5360delta

5.038

unicode15.0

"Unicode 15.0 is supported" in perl5380delta

^HOOK

"%{^HOOK} API introduced" in perl5380delta

Alias: keyword-hook

signature-default-operator

"Defined-or and logical-or assignment default expressions in signatures" in perl5380delta

INCDIR

"@INC Hook Enhancements and $INC and INCDIR" in perl5380delta

*{}

"Optimistic Eval in Patterns" in perl5380delta

Alias: optimistic-eval

REG_INF_I32_MAX

"REG_INF has been raised from 65,536 to 2,147,483,647" in perl5380delta

^LAST_SUCCESSFUL_PATTERN

"New regexp variable ${^LAST_SUCCESSFUL_PATTERN}" in perl5380delta

5.040

^^

"New ^^ logical xor operator" in perldelta

Alias: logical-xor

__CLASS__

"New __CLASS__ keyword" in perldelta.

:reader

":reader attribute for field variables" in perldelta

Removed Constructs

Only constructs not mentioned above are listed here, i.e. constructs that were introduced before 5.008001.

??

Removed in 5.022. See "Support for ?PATTERN? without explicit operator has been removed" in perl5220delta.

no-sigil

Removed in 5.022, not documented. Before that, if the first argument to shift, unshift, pop, push, splice, keys, values, and each was a global variable, it was possible to omit its sigil, e.g.

push arr, 12;  # same as push @arr, 12

for-qw

Removed in 5.018. See "qw(...)-can-no-longer-be-used-as-parentheses" in perl5180delta.

@_=split

Removed in 5.012, but documented in 5.014. See "split()-and-@_" in perl5140delta.

Alias: split-populates-@_

Accepted Features

Some features have been accepted in Perl (postderef and postderef_qq in 5.024, lexical_subs in 5.026). In the spirit of Syntax::Construct, you should still declare them, even if their usage has no effect in newer Perl versions to provide meaningful error messages to users of older versions.

AUTHOR

E. Choroba, <choroba at cpan.org>

Contributors

Gabor Szabo, JJ Merelo, tynovsky, Chris White, Mohammad S Anwar, Branislav Zahradnik

BUGS

Please report any bugs or feature requests to the GitHub repository, see below.

Unstable Perl Versions

In development versions of Perl, the removal of constructs is tested against the coming stable version -- e.g., 5.023 forbids all the removed constructs of 5.024. The behaviour of the module in such circumstances might still be, um, unstable.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Syntax::Construct

You can also look for information at:

SEE ALSO

Perl::MinimumVersion, Perl::MinimumVersion::Fast

LICENSE AND COPYRIGHT

Copyright 2013 - 2024 E. Choroba.

This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:

http://www.perlfoundation.org/artistic_license_2_0

Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.