Search code examples
perlsyntaxmojolicious

How Mojolicious modifies Perl syntax


Reading Mojolicious minions documentation I found the following code:

use v5.28;
use Mojolicious::Lite;
use experimental qw( signatures );
use Time::HiRes qw( time );

plugin Minion => {
    SQLite => 'sqlite:' . app->home->child('minion.db'),
};

# ...
app->start;

How did they create a new syntax plugin Minion => {...}? I've never seen it in classic Perl books. Is it a function call with a hash parameter: "Minion" being a key and a hashref {...} is a value?

Also they call app->start - app is a function returning a blessed hashref? But if it was a hash why "start" is not enclosed into braces? This syntax looks strange to me.


Solution

  • app is a function which returns $app which is an instance of Mojolicious::Lite=HASH

    app->start is same as app()->start

    https://github.com/mojolicious/mojo/blob/24d1d1987dbfbe27eaaa37dd5db692d2deb8d07f/lib/Mojolicious/Plugin/Config.pm#L12-L14

    "sub app; local *app = sub { \$app }; use Mojo::Base -strict; $content";
                                 |
                                 ^ not a reference but escape
                                 due to eval() of double quoted string
    

    Reproduction

    perl -MMojolicious::Lite -E 'no warnings; sub foo; local *foo = sub { app }; say for foo, app'
    

    output

    Mojolicious::Lite=HASH(0xe72080)
    Mojolicious::Lite=HASH(0xe72080)
    

    plugin is a regular function

    perl -MData::Dumper -wE 'sub plugin { print Dumper \@_ } plugin Minion => { SQLite => "sqlite:" }'
    $VAR1 = [
              'Minion',
              {
                'SQLite' => 'sqlite:'
              }
            ];
    

    You can add parens, and drop fat comma to look like the usual function call,

    plugin("Minion", { SQLite => "sqlite:" });