Modern::Perl::Prelude

License Perl CI

A small lexical prelude for writing modern-style Perl on Perl 5.26+.

What it enables by default

Default imported functions/features:

Optional imports

Flag-style

Supported flags:

Examples:

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:

use Modern::Perl::Prelude {
    utf8        => 1,
    defer       => 1,
    always_true => 1,
};

Supported hash keys:

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:

use Modern::Perl::Prelude '-utf8';

or:

use Modern::Perl::Prelude {
    utf8 => 1,
};

-class / 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 / defer

Enables Feature::Compat::Defer on demand:

use Modern::Perl::Prelude '-defer';

{
    defer { warn "leaving scope\n" };
    ...
}

-corinna / 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";
    }
}

Hash-style example:

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:

1;

Example module without 1;:

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:

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:

use Modern::Perl::Prelude {
    class   => 1,
    corinna => 1,
}; # dies

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 {
    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:

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:

no Modern::Perl::Prelude;

This reliably disables native pragmata/features managed directly by the module, such as:

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:

always_true is different: it is file-scoped, and you can explicitly disable it for the current file with:

no Modern::Perl::Prelude '-always_true';

or:

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:

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

Authors

License

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.