Projekt

Allgemein

Profil

Herunterladen (2,14 KB) Statistiken
| Zweig: | Markierung: | Revision:
972b8771 Sven Schöling
package SL::DB::Helper::Presenter;

use strict;

sub new {
# lightweight: 0: class, 1: object
bless [ $_[1], $_[2] ], $_[0];
}

sub AUTOLOAD {
our $AUTOLOAD;

my ($self, @args) = @_;

my $method = $AUTOLOAD;
$method =~ s/.*:://;

return if $method eq 'DESTROY';

43c3e3bc Moritz Bunkus
eval "require $self->[0]";

cef8c551 Sven Schöling
splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');

0e5e3501 Sven Schöling
if (my $sub = $self->[0]->can($method)) {
return $sub->($self->[1], @args);
}
972b8771 Sven Schöling
}

43c3e3bc Moritz Bunkus
sub can {
my ($self, $method) = @_;
eval "require $self->[0]";
$self->[0]->can($method);
}

972b8771 Sven Schöling
1;

__END__

=encoding utf-8

=head1 NAME

SL::DB::Helper::Presenter - proxy class to allow models to access presenters

=head1 SYNOPSIS

1918cfae Geoffrey Richardson
# assuming SL::Presenter::Part exists
972b8771 Sven Schöling
# and contains a sub link_to($class, $object) {}
SL::DB::Part->new(%args)->presenter->link_to

=head1 DESCRIPTION

1918cfae Geoffrey Richardson
When coding controllers one often encounters objects that are not crucial to
the current task, but must be presented in some form to the user. Instead of
972b8771 Sven Schöling
recreating that all the time the C<SL::Presenter> namepace was introduced to
hold such code.

Unfortunately the Presenter code is designed to be stateless and thus acts _on_
objects, but can't be instanced or wrapped. The early band-aid to that was to
export all sub-presenter calls into the main presenter namespace. Fixing it
1918cfae Geoffrey Richardson
would have meant accessing presenter functions like this:
972b8771 Sven Schöling
SL::Presenter::Object->method($object, %additional_args)

1918cfae Geoffrey Richardson
which is extremely inconvenient.
972b8771 Sven Schöling
This glue code allows C<SL::DB::Object> instances to access routines in their
presenter without additional boilerplate. C<SL::DB::Object> contains a
C<presenter> call for all objects, which will return an instance of this proxy
class. All calls on this will then be forwarded to the appropriate presenter.

=head1 INTERNAL STRUCTURE

1918cfae Geoffrey Richardson
The created proxy objects are lightweight blessed arrayrefs instead of the
usual blessed hashrefs. They only store two elements:
972b8771 Sven Schöling
=over 4

=item * The presenter class

=item * The invocing object

=back

Further delegation is done with C<AUTOLOAD>.

=head1 BUGS

None yet :)

=head1 AUTHOR

Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>

=cut