sub run_if_script {
my ( $self, @args ) = @_;
# ->to_psgi_app is true for require() but also works for plackup
- return $self->to_psgi_app if caller(1);
- $self = ref($self) ? $self : $self->_build_for_run_if_script(@args);
+ return $self->to_psgi_app(@args) if caller(1);
+ $self = ref($self) ? $self : $self->new(@args);
$self->run;
}
-sub _build_for_run_if_script {
- my ( $self, @args ) = @_;
- try { $self->new(@args) }
- catch {
- die "Failed to create new '$self' object during run_if_script"
- . " (should your .pm file end with just '1;'?) : $_\n";
- };
-}
-
sub _run_cgi {
my $self = shift;
require Plack::Handler::CGI;
}
sub to_psgi_app {
- my $self = ref($_[0]) ? $_[0] : $_[0]->new;
+ my ($invocant, @args) = @_;
+
+ unless (ref($invocant)) {
+ my $app;
+ return sub {
+ $app ||= do {
+ try { $invocant->new(@args)->to_psgi_app }
+ catch { die "Failed to auto-create new ${invocant} object for to_psgi_app: $_"; }
+ };
+ $app->(@_);
+ };
+ }
+
+ my $self = $invocant;
my $app = $self->_dispatcher->to_app;
# Close over $self to keep $self alive even though
mount '/another' => AnotherWSApp->to_psgi_app;
};
-This method can be called as a class method, in which case it implicitly
-calls ->new, or as an object method ... in which case it doesn't.
+This method can be called as a class method, in which case it will implicitly
+call ->new when the PSGI coderef is first invoked, or as an object method ...
+in which case it doesn't.
=head2 run
);
like(
- exception { DieTest->_build_for_run_if_script }, #
- qr/^Failed to create new 'DieTest' object during/,
+ exception { DieTest->run_if_script->() }, #
+ qr/^Failed to auto-create new DieTest object/,
"object creation in run_if_script decorates failure with useful information"
);