package Plack::Component; use strict; use warnings; use Carp (); use Plack::Util; use overload '&{}' => \&to_app_auto, fallback => 1; sub new { my $proto = shift; my $class = ref $proto || $proto; my $self; if (@_ == 1 && ref $_[0] eq 'HASH') { $self = bless {%{$_[0]}}, $class; } else { $self = bless {@_}, $class; } $self; } sub to_app_auto { my $self = shift; if (($ENV{PLACK_ENV} || '') eq 'development') { my $class = ref($self); warn "WARNING: Automatically converting $class instance to a PSGI code reference. " . "If you see this warning for each request, you probably need to explicitly call " . "to_app() i.e. $class->new(...)->to_app in your PSGI file.\n"; } $self->to_app(@_); } # NOTE: # this is for back-compat only, # future modules should use # Plack::Util::Accessor directly # or their own favorite accessor # generator. # - SL sub mk_accessors { my $self = shift; Plack::Util::Accessor::mk_accessors( ref( $self ) || $self, @_ ) } sub prepare_app { return } sub to_app { my $self = shift; $self->prepare_app; return sub { $self->call(@_) }; } sub response_cb { my($self, $res, $cb) = @_; Plack::Util::response_cb($res, $cb); } 1; __END__ =head1 NAME Plack::Component - Base class for PSGI endpoints =head1 SYNOPSIS package Plack::App::Foo; use parent qw( Plack::Component ); sub call { my($self, $env) = @_; # Do something with $env my $res = ...; # create a response ... # return the response return $res; } =head1 DESCRIPTION Plack::Component is the base class shared between L and C modules. If you are writing middleware, you should inherit from L, but if you are writing a Plack::App::* you should inherit from this directly. =head1 REQUIRED METHOD =over 4 =item call ($env) You are expected to implement a C method in your component. This is where all the work gets done. It receives the PSGI C<$env> hash-ref as an argument and is expected to return a proper PSGI response value. =back =head1 METHODS =over 4 =item new (%opts | \%opts) The constructor accepts either a hash or a hashref and uses that to create the instance. It will call no other methods and simply return the instance that is created. =item prepare_app This method is called by C and is meant as a hook to be used to prepare your component before it is packaged as a PSGI C<$app>. =item to_app This is the method used in several parts of the Plack infrastructure to convert your component into a PSGI C<$app>. You should not ever need to override this method; it is recommended to use C and C instead. =item response_cb This is a wrapper for C in L. See L for details. =back =head1 OBJECT LIFECYCLE Objects for the derived classes (Plack::App::* or Plack::Middleware::*) are created at the PSGI application compile phase using C, C and C, and the created object persists during the web server lifecycle, unless it is running on the non-persistent environment like CGI. C is invoked against the same object whenever a new request comes in. You can check if it is running in a persistent environment by checking C key in the C<$env> being true (non-persistent) or false (persistent), but it is best for you to write your middleware safely for a persistent environment. To accomplish that, you should avoid saving per-request data like C<$env> in your object. =head1 BACKWARDS COMPATIBILITY The L module used to inherit from L, which has been removed in favor of the L module. When developing new components it is recommended to use L like so: use Plack::Util::Accessor qw( foo bar baz ); However, in order to keep backwards compatibility this module provides a C method similar to L. New code should not use this and use L instead. =head1 SEE ALSO L L L =cut