kivitendo/SL/DB/Helper/Presenter.pm @ 43749680
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
|