Modern-Perl-Prelude
view release on metacpan or search on metacpan
# Modern::Perl::Prelude
[](https://dev.perl.org/licenses/)
[](https://www.perl.org/)
[](https://github.com/neo1ite/Modern-Perl-Prelude/actions/workflows/ci.yml)
A small lexical prelude for writing modern-style Perl on Perl 5.26+.
## What it enables by default
- `strict`
- `warnings`
- `feature qw(say state fc)`
- `Feature::Compat::Try`
- selected functions from `builtin::compat`
Default imported functions/features:
- `say`
- `state`
- `fc`
- `try` / `catch`
- `blessed`
- `refaddr`
- `reftype`
- `trim`
- `ceil`
- `floor`
- `true`
- `false`
- `weaken`
- `unweaken`
- `is_weak`
## Optional imports
### Flag-style
Supported flags:
- `-utf8`
- `-class`
- `-defer`
- `-corinna`
- `-always_true`
Examples:
```perl
use Modern::Perl::Prelude '-utf8';
use Modern::Perl::Prelude qw(
-class
-defer
);
use Modern::Perl::Prelude qw(
-class
-utf8
-always_true
);
```
### Hash-style
Hash-style arguments are supported as a **single hash reference**:
```perl
use Modern::Perl::Prelude {
utf8 => 1,
defer => 1,
always_true => 1,
};
```
Supported hash keys:
- `utf8`
- `class`
- `defer`
- `corinna`
- `always_true`
For compatibility-layer options (`class`, `defer`, `corinna`), a true scalar enables the option. A hash reference also enables it and is passed through to the underlying module's `import`.
For `always_true`, use a boolean value.
### `-utf8` / `utf8`
Enables source-level UTF-8, like:
```perl
use Modern::Perl::Prelude '-utf8';
```
or:
```perl
use Modern::Perl::Prelude {
utf8 => 1,
};
```
### `-class` / `class`
Enables `Feature::Compat::Class` on demand:
```perl
use Modern::Perl::Prelude '-class';
class Point {
field $x :param = 0;
field $y :param = 0;
method sum {
return $x + $y;
}
}
```
### `-defer` / `defer`
Enables `Feature::Compat::Defer` on demand:
```perl
use Modern::Perl::Prelude '-defer';
{
defer { warn "leaving scope\n" };
...
}
```
### `-corinna` / `corinna`
Enables direct `Object::Pad` / Corinna-like syntax on demand:
```perl
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";
}
}
```
Hash-style example:
```perl
use Modern::Perl::Prelude {
corinna => {},
utf8 => 1,
};
```
### `-always_true` / `always_true`
Enables automatic true return for the currently-compiling file, so a module can omit the trailing:
```perl
1;
```
Example module without `1;`:
```perl
use Modern::Perl::Prelude qw(
-class
-utf8
-always_true
);
class My::App::Person {
field $name :param;
field $age :param = 0;
method greet {
return "Hello, I'm $name and I'm $age years old";
}
}
```
Hash-style example:
```perl
use Modern::Perl::Prelude {
class => 1,
utf8 => 1,
always_true => 1,
};
class My::App::Person {
field $name :param;
}
```
## Option compatibility rules
Any non-conflicting combination is allowed.
`-class` and `-corinna` are intentionally mutually exclusive.
The same rule applies to hash-style arguments:
```perl
use Modern::Perl::Prelude {
class => 1,
corinna => 1,
}; # dies
```
## Usage
Basic usage:
```perl
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`:
```perl
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`:
```perl
use Modern::Perl::Prelude {
corinna => {},
utf8 => 1,
};
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;
```
With `always_true` for a module file:
```perl
use Modern::Perl::Prelude qw(
-class
-utf8
-always_true
);
class My::App::Person {
field $name :param;
}
# no trailing 1;
```
## Lexical disabling
You can disable native pragmata/features lexically again:
```perl
no Modern::Perl::Prelude;
```
This reliably disables native pragmata/features managed directly by the module, such as:
- `strict`
- `warnings`
- `say`
- `state`
- `fc`
- `utf8`
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:
```perl
no Modern::Perl::Prelude;
```
This applies to:
- `Feature::Compat::Try`
- `Feature::Compat::Class`
- `Feature::Compat::Defer`
- `Object::Pad`
- `builtin::compat`
`always_true` is different: it is file-scoped, and you can explicitly disable it for the current file with:
```perl
no Modern::Perl::Prelude '-always_true';
```
or:
```perl
no Modern::Perl::Prelude { always_true => 1 };
```
## 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.
`always_true` is implemented via the CPAN module `true` and is file-scoped rather than lexically-scoped.
## Install
Using `MakeMaker`:
```shell
perl Makefile.PL
make
make test
make install
```
Using `cpanm` for dependencies:
```shell
cpanm --installdeps .
```
Including author/develop dependencies:
```shell
cpanm --with-develop --installdeps .
```
## Test
Run normal tests:
```shell
make test
```
Run author tests:
```shell
prove -lv xt/author
```
Run coverage:
```shell
cover -delete
HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr t xt/author
cover
```
## Current status
- Normal test suite: passing
( run in 2.243 seconds using v1.01-cache-2.11-cpan-aadc1410aed )