Modern::Perl::Prelude
A small lexical prelude for writing modern-style Perl on Perl 5.30+.
What it enables by default
strictwarningsfeature qw(say state fc)Feature::Compat::Try- selected functions from
builtin::compat
Default imported functions/features:
saystatefctry/catchblessedrefaddrreftypetrimceilfloortruefalseweakenunweakenis_weak
Optional imports
-utf8
Enables source-level UTF-8, like:
use Modern::Perl::Prelude '-utf8';
-class
Enables Feature::Compat::Class on demand:
use Modern::Perl::Prelude '-class';
class Point {
field $x :param = 0;
field $y :param = 0;
method sum {
return $x + $y;
}
}
-defer
Enables Feature::Compat::Defer on demand:
use Modern::Perl::Prelude '-defer';
{
defer { warn "leaving scope\n" };
...
}
-corinna
Enables direct Object::Pad / Corinna-like syntax on demand:
use Modern::Perl::Prelude '-corinna';
class Person {
field $name :param;
field $age :param = 0;
method greet {
return "Hello, I'm $name and I'm $age years old";
}
}
Combined options
Any non-conflicting combination is allowed:
use Modern::Perl::Prelude qw(
-utf8
-defer
);
-class and -corinna are intentionally mutually exclusive.
Usage
Basic usage:
use Modern::Perl::Prelude;
state $counter = 0;
my $s = trim(" hello ");
my $folded = fc("Straße");
try {
die "boom\n";
}
catch ($e) {
warn $e;
}
With Feature::Compat::Class:
use Modern::Perl::Prelude qw(
-class
-defer
);
class Example {
field $value :param = 0;
method value {
return $value;
}
}
{
defer { warn "scope ended\n" };
my $obj = Example->new(value => 42);
say $obj->value;
}
With Object::Pad:
use Modern::Perl::Prelude qw(
-corinna
-utf8
);
class Person {
field $name :param;
field $age :param = 0;
method greet {
return "Hello, I'm $name and I'm $age years old";
}
}
my $p = Person->new(name => 'José');
say $p->greet;
Lexical disabling
You can disable native pragmata/features lexically again:
no Modern::Perl::Prelude;
This reliably disables native pragmata/features managed directly by the module, such as:
strictwarningssaystatefcutf8
Compatibility layers are treated as import-only for cross-version use on Perl 5.30+, so they are not guaranteed to be symmetrically undone by:
no Modern::Perl::Prelude;
This applies to:
Feature::Compat::TryFeature::Compat::ClassFeature::Compat::DeferObject::Padbuiltin::compat
Design goals
This module is intended as a small project prelude for codebases that want a more modern Perl style while keeping runtime compatibility with Perl 5.30+.
It is implemented as a lexical wrapper using Import::Into, so pragmata and lexical features affect the caller's scope rather than the wrapper module itself.
Optional compatibility layers are loaded lazily and only when explicitly requested.
Install
Using MakeMaker:
perl Makefile.PL
make
make test
make install
Using cpanm for dependencies:
cpanm --installdeps .
Including author/develop dependencies:
cpanm --with-develop --installdeps .
Test
Run normal tests:
make test
Run author tests:
prove -lv xt/author
Run coverage:
cover -delete
HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr t xt/author
cover
Current status
- Normal test suite: passing
- Author tests: passing
- POD coverage: passing
- Devel::Cover coverage: 100%
License
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Changes
Revision history for Modern::Perl::Prelude
0.006 2026-03-22
- Add optional -corinna import via Object::Pad
- Make -class and -corinna mutually exclusive
- Add t/05-corinna.t with Object::Pad coverage
- Add Object::Pad to test dependencies
- Refresh README to document -corinna correctly
- Add t/05-corinna.t to MANIFEST and author EOL checks
0.005 2026-03-17
- Add optional -class import via Feature::Compat::Class
- Add optional -defer import via Feature::Compat::Defer
- Keep new compat layers lazy-loaded so existing default import behavior stays unchanged
- Add t/04-class-defer.t to cover optional compat imports
- Update packaging metadata and author EOL coverage for new test file
- Add author and git information
0.004 2026-03-17
- Add argument handling tests in t/03-args.t
- Reach 100% statement, branch, subroutine and total coverage
- Fix UTF-8 option tests to match real lexical behavior
- Silence once-only package variable warning in args test
- Finalize test suite for use/no and option validation paths
0.003 2026-03-17
- Make unimport honest: only undo native pragmata/features
- Fix no.t to test only reliably reversible native features
- Clarify POD about import-only compat layers
0.002 2026-03-17
- Add unimport support: no Modern::Perl::Prelude
- Add author tests
- Add GitHub Actions CI matrix for Perl 5.30 .. 5.42
- Add cpanfile
- Refresh distribution skeleton
0.001 2026-03-17
- First version