Skip to content

Instantly share code, notes, and snippets.

@kraih
Last active December 10, 2015 00:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kraih/4351674 to your computer and use it in GitHub Desktop.
Save kraih/4351674 to your computer and use it in GitHub Desktop.
use Mojolicious::Lite;
use Mojolicious::Lite::MyKeywords;
get_post '/' => sub {
render text => 'Hello keywords!';
};
app->start;
package Mojolicious::Lite::MyKeywords;
use Mojo::Base -base;
use Mojo::Util 'monkey_patch';
sub import {
my $caller = caller;
# Export "get_post" keyword (reuse "any" keyword to make "under" work)
monkey_patch $caller, 'get_post', sub {
return $caller->can('any')->([qw(GET POST)] => @_);
};
# Add magical "current_controller" helper for "render" keyword
$caller->app->hook(
around_dispatch => sub {
my ($next, $c) = @_;
local $c->app->renderer->helpers->{current_controller} = sub {$c};
$next->();
}
);
# Export "render" keyword (does not work for delayed rendering)
monkey_patch $caller, 'render', sub {
return $caller->app->current_controller->render(@_);
};
}
1;
@kraih
Copy link
Author

kraih commented Nov 28, 2014

In case you're wondering why we don't do this in Mojolicious. The following example application would not work, due to context switching to the event loop, before using the render keyword.

use Mojolicious::Lite;
use Mojolicious::Lite::MyKeywords;

get_post '/' => sub {
  Mojo::IOLoop->timer(3 => sub {
    render text => 'Hello keywords!';
  });
};

app->start;

This kind of DSL requires global state, which gets in the way of concurrency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment