Modern-Perl
view release on metacpan or search on metacpan
Revision history for Modern::Perl
1.20250607 2025-06-07 16:56:19-07:00 America/Los_Angeles
- update for 2025 year bundle
- enhance documentation to discourage this module for v5.38 and newer
1.20241001 2024-09-30 19:12:47-07:00 America/Los_Angeles
- fix switch tests after Perl 5.41.4 removal of deprecated feature (RT #155822, Slaven Rezic)
1.20240120 2024-01-20 12:15:09-08:00 America/Los_Angeles
- fix tests for Perl < 5.26.0 (RT #151198, Slaven Rezic)
- fix tests for Perl 5.32 (Tony Cook, RT #131608)
- update for 2020
1.20190727 2019-07-27 12:15:27-07:00 America/Los_Angeles
- remove explicit autodie dependency (GH #11, gordon-fish, mst, #perl)
- add description of odern::Perl module (Utkarsh Gupta, Debian, GH issue #12)
1.20190601 2019-06-01 09:19:36-07:00 America/Los_Angeles
- update for 2019
- reduce scope of lexical %dates (RT #128406)
- support `perl -Modern::Perl=20xx` (RT #96319)
1.20181021 2018-10-21 12:09:32-07:00 America/Los_Angeles
- autogenerate META.json file (Mohammad S Anwar, GH PR #7)
- remove Module::Build build dependency to make installation easier
1.20180928 2018-09-27 18:29:25-07:00 America/Los_Angeles
- skip tests for Perls without arraybase (Dagfinn Ilmari Mannsåker, GH #10)
1.20180901 2018-09-01 12:19:53-07:00 America/Los_Angeles
- skip tests when PERL5OPT is set (David Precious, GH #9)
Makefile.PL view on Meta::CPAN
my %WriteMakefileArgs = (
"ABSTRACT" => "enable all of the features of Modern Perl with one import",
"AUTHOR" => "chromatic",
"CONFIGURE_REQUIRES" => {
"ExtUtils::MakeMaker" => 0
},
"DISTNAME" => "Modern-Perl",
"LICENSE" => "perl",
"MIN_PERL_VERSION" => "5.010",
"NAME" => "Modern::Perl",
"PREREQ_PM" => {
"IO::File" => 0,
"IO::Handle" => 0,
"feature" => 0,
"mro" => 0,
"strict" => 0,
"warnings" => 0
},
"TEST_REQUIRES" => {
"Cwd" => 0,
Modern::Perl
------------
Modern Perl often relies on the presence of several core and CPAN pragmas and
modules. Wouldn't it be nice to use them all with a single command? Try this
one:
use Modern::Perl;
*NOTE* that Perl versions 5.38 and newer effectively do the same thing with:
use v5.38; # or v5.40, v5.42, etc
... so if you're writing code with those language versions, you may not need
this module at all!
INSTALLATION
$ perl Build.PL
$ perl ./Build
$ perl ./Build test
$ sudo perl ./Build install
SUPPORT AND DOCUMENTATION
After installing, you can find documentation for this module with the
perldoc command.
perldoc Modern::Perl
You can also look for information at:
RT, CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Modern-Perl
AnnoCPAN, Annotated CPAN documentation
http://annocpan.org/dist/Modern-Perl
CPAN Ratings
lib/Modern/Perl.pm view on Meta::CPAN
package Modern::Perl;
# ABSTRACT: enable all of the features of Modern Perl with one import
$Modern::Perl::VERSION = '1.20250607';
use 5.010_000;
use strict;
use warnings;
use mro ();
use feature ();
# enable methods on filehandles; unnecessary when 5.14 autoloads them
use IO::File ();
use IO::Handle ();
my $wanted_date;
sub VERSION {
my ($self, $version) = @_;
my $default = 2025;
return $Modern::Perl::VERSION || $default unless defined $version;
return $Modern::Perl::VERSION || $default if $version < 2009;
$wanted_date = $version if (caller(1))[3] =~ /::BEGIN/;
return $default;
}
my $unimport_tag;
BEGIN {
$unimport_tag = $] > 5.015 ? ':all' : ':5.10';
}
lib/Modern/Perl.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Modern::Perl - enable all of the features of Modern Perl with one import
=head1 VERSION
version 1.20250607
=head1 SYNOPSIS
Modern Perl programs use several modules to enable additional features of Perl
and of the CPAN. Instead of copying and pasting all of these C<use> lines,
instead write only one:
use Modern::Perl;
This enables the L<strict> and L<warnings> pragmas, as well as all of the
features available in Perl 5.10. It also enables C3 method resolution order as
documented in C<perldoc mro> and loads L<IO::File> and L<IO::Handle> so that
you may call methods on filehandles. In the future, it may include additional
core modules and pragmas (but is unlikely to include non-core features).
Because so much of this module's behavior uses lexically scoped pragmas, you
may disable these pragmas within an inner scope with:
no Modern::Perl;
See L<http://www.modernperlbooks.com/mt/2009/01/toward-a-modernperl.html> for
more information, L<http://www.modernperlbooks.com/> for further discussion of
Modern Perl and its implications, and
L<http://onyxneon.com/books/modern_perl/index.html> for a freely-downloadable
Modern Perl tutorial.
=head2 CLI Usage
As of Modern::Perl 2019, you may also enable this pragma from the command line:
$ perl -Modern::Perl -e 'say "Take that, awk!"'
You may also enable year-specific features:
$ perl -Modern::Perl=2020 -e 'say "Looking forward to Perl 5.30!"'
=head2 Wrapping Modern::Perl
If you want to wrap Modern::Perl in your own C<import()> method, you can do so
to add additional pragmas or features, such as the use of L<Try::Tiny>. Please
note that, if you do so, you will I<not> automatically enable C3 method
resolution in the calling scope. This is due to how the L<mro> pragma works. In
your custom C<import()> method, you will need to write code such as:
mro::set_mro( scalar caller(), 'c3' );
=head2 Forward Compatibility
For forward compatibility, I recommend you specify a string containing a
I<year> value as the single optional import tag. For example:
use Modern::Perl '2009';
use Modern::Perl '2010';
... both enable 5.10 features, while:
use Modern::Perl '2011';
... enables 5.12 features:
use Modern::Perl '2012';
... enables 5.14 features:
use Modern::Perl '2013';
... enables 5.16 features, and:
use Modern::Perl '2014';
... enables 5.18 features, and:
use Modern::Perl '2015';
... enables 5.20 features, and:
use Modern::Perl '2016';
... enables 5.24 features, and:
use Modern::Perl '2017';
... enables 5.24 features, and:
use Modern::Perl '2018';
... enables 5.26 features, and:
use Modern::Perl '2019';
... enables 5.28 features, and:
use Modern::Perl '2020';
... enables 5.30 features, and:
use Modern::Perl '2021';
... enables 5.32 features, and:
use Modern::Perl '2022';
... enables 5.34 features, and:
use Modern::Perl '2023';
... enables 5.36 features, and:
use Modern::Perl '2024';
... enables 5.38 features, and:
use Modern::Perl '2025';
... enables 5.40 features.
Obviously you cannot use newer features on earlier versions. Perl will throw
the appropriate exception if you try.
As of Perl 5.38, you may prefer to write C<use v5.38>, which is almost entirely
equivalent to the use of this module. For the purpose of forward compatibility,
this module will continue to work as expected--and will continue regular
maintenance.
lib/Modern/Perl.pm view on Meta::CPAN
Please report any bugs or feature requests to C<bug-modern-perl at
rt.cpan.org>, or through the web interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Modern-Perl>. I will be
notified, and then you'll automatically be notified of progress on your bug as
I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Modern::Perl
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Modern-Perl>
=item * AnnoCPAN: Annotated CPAN documentation
lib/odern/Perl.pm view on Meta::CPAN
package odern::Perl;
#ABSTRACT: Module for enabling all of the features of Modern Perl
$odern::Perl::VERSION = '1.20250607';
use Modern::Perl;
*import = \&Modern::Perl::import;
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
#! perl
use Test::More 0.98;
BEGIN
{
delete $INC{'IO/File.pm'};
delete $INC{'IO/Handle.pm'};
use_ok( 'Modern::Perl' ) or exit;
ok $INC{'IO/File.pm'}, 'M::P should load IO::File';
ok $INC{'IO/Handle.pm'}, 'M::P should load IO::Handle';
Modern::Perl->import();
}
eval 'say "# say() should be available";';
is( $@, '', 'say() should be available' );
eval '$x = 1;';
like( $@, qr/Global symbol "\$x" requires explicit/,
'strict should be enabled' );
my $warnings;
package B;
@B::ISA = 'A';
package C;
@C::ISA = 'A';
package D;
use Modern::Perl;
@D::ISA = qw( B C );
END_CLASSES
package main;
is_deeply( mro::get_linear_isa( 'D' ), [qw( D B C A )], 'mro should use C3' );
if ($] > 5.011003)
{
eval q|
use Modern::Perl;
BEGIN
{
ok exists $^H{feature_unicode},
'... and should unilaterally enable unicode_strings, when available';
}
|;
}
done_testing;
t/regressions.t view on Meta::CPAN
#! perl
use Test::More 0.98;
use Modern::Perl ();
if ($ENV{PERL5OPT}) {
plan( skip_all => "Cannot reliably test with PERL5OPT set" );
exit 0;
}
$SIG{__WARN__} = sub
{
return if $_[0] =~ /Number found where operator expected/;
return if $_[0] =~ /Do you need to predeclare/;
return if $_[0] =~ /future reserved word/;
return if $_[0] =~ /given is (experimental|deprecated)/;
warn shift
};
eval 'sub { given (0) {} }';
isnt $@, '', 'use Modern::Perl () does not enable switch';
eval 'sub { say 0 }';
isnt $@, '', 'use Modern::Perl () does not enable say';
eval 'state $x;';
isnt $@, '', 'use Modern::Perl () does not enable state';
is uc "\xdf", "\xdf", 'Modern::Perl () does not enable unicode_strings';
sub test_switch {
my $version = shift;
return if $] >= 5.041004;
eval "use Modern::Perl $version; sub { given (0) {} }";
is $@, '', qq|use Modern::Perl $version enables switch|;
}
{
use Modern::Perl 2009;
eval 'sub { say 0 }';
test_switch(2009);
is $@, '', q|use Modern::Perl 2009 enables say|;
eval 'state $x';
is $@, '', q|use Modern::Perl 2009 enables state|;
is uc "\xdf", "\xdf", 'but not unicode_strings';
}
{
use Modern::Perl 2010;
test_switch(2010);
eval 'sub { say 0 }';
is $@, '', q|use Modern::Perl 2010 enables say|;
eval 'state $x';
is $@, '', q|use Modern::Perl 2010 enables state|;
is uc "\xdf", "\xdf", 'but not unicode_strings';
}
if ($] >= 5.012)
{
eval <<'END_HERE';
use Modern::Perl 2011;
test_switch(2011);
eval 'sub { say 0 }';
is $@, '', q|use Modern::Perl 2011 enables say|;
eval 'state $x';
is $@, '', q|use Modern::Perl 2011 enables state|;
is uc "\xdf", "SS", '2011 enables unicode_strings';
END_HERE
}
if ($] >= 5.014)
{
eval <<'END_HERE';
use Modern::Perl 2012;
test_switch(2012);
eval 'sub { say 0 }';
is $@, '', q|use Modern::Perl 2012 enables say|;
eval 'state $x';
is $@, '', q|use Modern::Perl 2012 enables state|;
is uc "\xdf", "SS", '2012 enables unicode_strings';
END_HERE
}
eval 'sub { given (0) {} }';
isnt $@, "", 'switch feature does not leak out';
eval 'sub { say 0 }';
isnt $@, '', 'say feature does not leak out';
eval 'state $x';
isnt $@, '', 'state feature does not leak out';
is uc "\xdf", "\xdf", 'unicode_strings feature does not leak out';
# RT #80304: warning on Modern::Perl->VERSION()
{
my $warning = '';
local $SIG{__WARN__} = sub { $warning = shift };
$Modern::Perl::VERSION ||= '1.20121103';
my $version = Modern::Perl->VERSION;
like $version, qr/1\.20\d/,
'VERSION() should return version number, given no argument';
is $warning, '', '... without warning about undef argument';
}
done_testing;
t/unimport.t view on Meta::CPAN
#! perl
use Test::More 0.98;
use Modern::Perl;
if ($ENV{PERL5OPT}) {
plan( skip_all => "Cannot reliably test with PERL5OPT set" );
exit 0;
}
eval 'say "# say() should be available";';
is $@, '', 'say() should be available';
{
no Modern::Perl;
eval 'say "# say() should be unavailable when unimported"';
like $@, qr/syntax error.+near "say /,
'unimport should disable say feature';
eval '$x = 1';
is $@, '', 'unimport should disable strictures';
my $warnings;
local $SIG{__WARN__} = sub { $warnings = shift };
my $y =~ s/hi//;
unlike $warnings, qr/Use of uninitialized value/,
t/year_imports.t view on Meta::CPAN
#! perl
use Test::More 0.98;
use Modern::Perl ();
use Cwd;
use File::Spec;
if ($ENV{PERL5OPT}) {
plan( skip_all => "Cannot reliably test with PERL5OPT set" );
exit 0;
}
$SIG{__WARN__} = sub
{
t/year_imports.t view on Meta::CPAN
my $year = shift;
return $year eq '()' ? $year : "'$year'";
}
sub test_lexical_subs_for
{
# lexical subs removed from feature.pm in 5.25.2
return if $] >= 5.025002;
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; my sub foo {}|;
isnt $@, '', qq|use Modern::Perl $year should not enable lexical subs|;
}
sub test_switch_for {
# given removed in 5.41.4
return if $] >= 5.041004;
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; sub { given (0) {} }|;
is $@, '', qq|use Modern::Perl $year enables switch|;
}
sub test_no_switch_for {
# given removed in 5.41.4
return if $] >= 5.041004;
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; sub { given (0) {} }|;
isnt $@, '', qq|use Modern::Perl $year does not enable switch|;
}
sub test_no_indirect_for {
my $year = _get_year(shift);
my $warning = '';
local $SIG{__WARN__} = sub { $warning = shift };
eval qq|use Modern::Perl $year; my \$foo = new Modern::Perl;|;
like $@, qr/syntax error.+near "new Modern::Perl"/,
qq|use Modern::Perl $year disables indirect method calls|;
}
sub test_no_multidimensional_for {
my $year = _get_year(shift);
my $warning = '';
local $SIG{__WARN__} = sub { $warning = shift };
eval qq{
use Modern::Perl $year;
my (\$x, \$y) = (1, 2);
my %foo;
\$foo{\$x, \$y} = 'bar';
};
like $@, qr/Multidimensional hash lookup is disabled/,
qq|use Modern::Perl $year disables multidimensional array emulation|;
}
sub test_say_for {
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; sub { say 0 }|;
is $@, '', qq|use Modern::Perl $year enables say|;
}
sub test_state_for {
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; state \$x;|;
is $@, '', qq|use Modern::Perl $year enables state|;
}
sub test_cur_sub_for {
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; sub { return __SUB__ }|;
is $@, '', qq|use Modern::Perl $year enables current_sub|;
}
sub test_array_base_for {
my $year = _get_year(shift);
my $warning = '';
local $SIG{__WARN__} = sub { $warning = shift };
if (eval qq|use Modern::Perl $year; \$[ = 10|) {
like $warning, qr/Use of assignment to \$\[ is deprecated/,
qq|use Modern::Perl $year disables array_base|;
}
else {
like $@, qr/Assigning non-zero to \$\[ is no longer possible/,
qq|use Modern::Perl $year works without array_base|;
}
}
sub test_fc_for {
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; fc("tschüÃ") eq fc("TSCHÃSS")|;
is $@, '', qq|use Modern::Perl $year enables fc|;
}
sub test_postderef_for {
my $year = _get_year(shift);
eval qq|use Modern::Perl $year; my \$r = [ 1, [ 2, 3 ], 4 ]; \$r->[1]->@*|;
is $@, '', qq|use Modern::Perl $year enables postderef_qq|;
}
sub test_unicode_strings_for {
my $year = _get_year(shift);
eval qq{
use Modern::Perl $year;
is uc "\xdf", "SS", q|use Modern::Perl $year enables unicode_strings|;
};
}
sub test_signatures_for {
my $year = _get_year(shift);
my @warnings;
local $SIG{__WARN__} = sub { push @warnings, @_ };
local $@;
my ($yearnum) = $year =~ m/(\d+)/;
eval qq{
use Modern::Perl $year;
sub foo_$yearnum( \$bar ) { ... }
};
is $@, '', qq|use Modern::Perl $year enables signatures|;
is @warnings, 0, '... and disables signature warnings';
}
sub test_isa_for {
my $year = _get_year(shift);
eval qq{
use Modern::Perl $year;
my \$foo = bless {}, 'Some::Class';
my \$result = \$foo isa 'Some::Class';
};
is $@, '', qq|use Modern::Perl $year enables isa|;
}
sub test_warnings_for {
my $year = _get_year(shift);
my $warnings;
local $SIG{__WARN__} = sub { $warnings = shift };
eval qq{
no warnings;
use Modern::Perl $year;
my \$x = "2:" + 3;
};
like $warnings, qr/Argument "2:" isn't numeric/, qq|use Modern::Perl $year enables warnings|;
}
sub test_module_true_for {
my $year = _get_year(shift);
my $cwd = Cwd::cwd();
my $tmpdir = File::Spec->tmpdir;
chdir $tmpdir;
open my $fh, '>', 'Foo.pm'
or die "Cannot write 'Foo.pm': $!\n";
# don't use <<~ heredoc to trim whitespace
# as this will fail with Perl < 5.26
# see RT #151189
$fh->print(<<EOF);
package Foo;
use Modern::Perl $year;
sub bar { 'returned from Foo::bar()' }
return 0;
EOF
close $fh;
local @INC = '.';
my $result;
eval qq{
use Foo;
\$result = Foo->bar;
};
is $result, 'returned from Foo::bar()',
qq|use Modern::Perl $year enables module_true|;
chdir $cwd;
}
eval 'sub { given (0) {} }';
isnt $@, '', 'use Modern::Perl () does not enable switch';
eval 'sub { say 0 }';
isnt $@, '', 'use Modern::Perl () does not enable say';
eval 'state $x;';
isnt $@, '', 'use Modern::Perl () does not enable state';
is uc "\xdf", "\xdf", 'Modern::Perl () does not enable unicode_strings';
eval 'sub { return __SUB__ }';
is $@, '', q|use Modern::Perl '2013' does not enable current_sub|;
{
my $warning = '';
local $SIG{__WARN__} = sub { $warning = shift };
eval 'fc("tschüÃ") eq fc("TSCHÃSS")';
isnt $@, '', q|use Modern::Perl () does not enable fc|;
}
{
use Modern::Perl '2009';
test_switch_for( '2009' );
test_say_for( '2009' );
test_state_for( '2009' );
is uc "\xdf", "\xdf", q|use Modern::Perl '2009' does not enable unicode_strings|;
}
{
use Modern::Perl '2010';
test_switch_for( '2010' );
test_say_for( '2010' );
test_state_for( '2010' );
is uc "\xdf", "\xdf", q|use Modern::Perl '2010' does not enable unicode_strings|;
}
if ($] >= 5.012)
{
my $year = 2011;
test_switch_for( $year );
test_say_for( $year );
test_state_for( $year );
test_unicode_strings_for( $year );
( run in 0.302 second using v1.01-cache-2.11-cpan-4d50c553e7e )