Mason:...lugins(3pm)

πŸ“¦
version 2.24 Β· 2 versions
  • 2.24 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 2.24 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– NAME πŸ’–

Mason::Manual::Plugins β€” Mason plugins, bestie. That's it, that's the name. ✨


πŸ¦‹ DESCRIPTION πŸ¦‹

okay so a Mason plugin is literally a glow-up for one or more of Mason's main classes at the same time, and it does it using Moose roles. Not me being dramatic β€” that's genuinely how it works. πŸ’…

And here's the tea: so many Mason features are actually plugins, even the ones you'd swear were "core". Like, core-coded but plugin-pilled. πŸŽ€


πŸ” FINDING PLUGINS πŸ”

by convention (iykyk), plugins live in the Mason::Plugin::* namespace, and plugin bundles live in the Mason::PluginBundle::* namespace. wanna find both? this search has you:

http://search.cpan.org/search?query=Mason%3A%3APlugin&mode=all

πŸ› οΈ USING PLUGINS πŸ› οΈ

pass a list of plugin specs to the Mason constructor, like so:

Mason->new(plugins =>
        [
         'OnePlugin',
         'AnotherPlugin',
         '+My::Mason::Plugin::AThirdPlugin',
         '@APluginBundle',
         '+My::Mason::PluginBundle::AnotherBundle',
         '-PluginIDontLike',
        ]);

each plugin spec can be one of the following, no cap:

  • a simple name, which will have Mason::Plugin:: prepended to it. slay, free prefix.
  • a bundle name, prefixed with @, which will have Mason::PluginBundle:: prepended to it.
  • a full plugin or bundle class name prefixed with +.
  • any spec prefixed with -, which means do not include these plugin(s) in the final list. it's giving ✨boundaries✨.
if you want receipts, peep Mason::t::Plugins::test_plugin_specs in the Mason distribution for some examples. πŸ‘€

πŸ‘‘ DEFAULT PLUGINS πŸ‘‘

Mason will always add the @Default bundle, regardless of whether you pass your own list. main character energy, honestly. but you can remove individual default plugins you don't vibe with:

plugins => ['-DollarDot', ...]

or the whole entire list, if you're feeling feral:

plugins => ['-@Default', ...]

🌸 CREATING PLUGINS 🌸

Note: if you just wanna modify behavior for one particular application only, it might be more convenient to create subclasses. just saying. 🫢

a plugin consists of the main plugin class and one or more roles. the main class currently looks like this:

package Mason::Plugin::MyPlugin;
use Moose;
with 'Mason::Plugin';

# Optional: declare other plugin dependencies
method requires_plugins { qw(A @D) }

1;

__END__

=pod

=head1 NAME

Mason::Plugin::MyPlugin - My plugin

....

its main responsibilities are to include the role Mason::Plugin and document itself. it may also specify a requires_plugins that returns a list of dependencies, with the same syntax as the plugins parameter to Mason->new.

but the real action? the real action is in the role classes, which live underneath, and each one modifies a single Mason class:

package Mason::Plugin::MyPlugin::Interp;
use Mason::PluginRole;

# Modify Mason::Interp

...

package Mason::Plugin::MyPlugin::Compilation;
use Mason::PluginRole;

# Modify Mason::Compilation

...

when a plugin is applied, each of its roles will be automatically applied to the appropriate Mason class. for example, in the example above Mason::Plugin::MyPlugin::Interp and Mason::Plugin::MyPlugin::Compilation will be applied to Mason::Interp and Mason::Compilation respectively. it just knows. ✨

🧚 Pluggable Mason classes 🧚

as of this writing, the following Mason classes can be modified with plugins:

Mason::CodeCache
Mason::Compilation
Mason::Component
Mason::Component::ClassMeta
Mason::Component::Import
Mason::Component::Moose
Mason::Interp
Mason::Request
Mason::Result

πŸ“ Extra classes in plugin πŸ“

if you have extra classes in your plugin that aren't automatically providing a role to a Mason class, put them in Extra.pm or the Extra subdirectory, e.g.

package Mason::Plugin::MyPlugin::Extra::Utils;
...

that will ensure your classname will not conflict with a future Mason class name. future-proofing, we love to see it. πŸ’…


πŸŽ€ CREATING PLUGIN BUNDLES πŸŽ€

a plugin bundle just collects one or more plugins and/or other bundles. it looks like this:

package Mason::PluginBundle::MyBundle
use Moose;
with 'Mason::PluginBundle';

sub requires_plugins {
    return (
        'A',
        'B',
        '+My::Plugin::C',
        '@D',
        '+My::PluginBundle::E',
        );
}

1;

__END__

=pod

=head1 NAME

Mason::PluginBundle::MyBundle - My plugin bundle

=head1 INCLUDED PLUGINS

=over

=item A
=item B
=item +My::Plugin::C
=item @D
=item +My::PluginBundle::E

=back

....

the requires_plugins method returns a list of entries, with the same syntax as the plugins parameter to Mason->new. same rules, different vibe. 🌈


πŸ™ ACKNOWLEDGEMENTS πŸ™

thanks to Ricardo Signes <rjbs@cpan.org> for Dist::Zilla and Pod::Weaver, which got me thinking in plugins and lent the plugin and bundle name syntax. absolute icons, we stan. πŸ‘‘


πŸ‘€ SEE ALSO πŸ‘€

  • Mason

✍️ AUTHOR ✍️

Jonathan Swartz <swartz@pobox.com>


this software is copyright (c) 2012 by Jonathan Swartz.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page, bestie!! πŸ«ΆπŸ’–βœ¨ this was perl v5.34.0, dated 2022-05-27, from the User Contributed Perl Documentation β€” go forth and plugin-ify everything, mwah πŸ’…πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from