File Coverage

lib/Class/Facade.pm
Criterion Covered Total %
statement 35 36 97.2
branch 5 6 83.3
condition 4 6 66.6
subroutine 8 8 100.0
pod 1 1 100.0
total 53 57 92.9


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # Class::Facade
4             #
5             # DESCRIPTION
6             # Facade class for providing a unified interface to one or more
7             # delegate objects.
8             #
9             # AUTHOR
10             # Andy Wardley
11             #
12             # COPYRIGHT
13             # Copyright (C) 2001-2002 Andy Wardley. All Rights Reserved.
14             #
15             # This module is free software; you can redistribute it and/or
16             # modify it under the same terms as Perl itself.
17             #
18             # REVISION
19             # $Id$
20             #
21             #========================================================================
22              
23             package Class::Facade;
24              
25 1     1   1869 use strict;
  1         1  
  1         25  
26 1     1   902 use Class::Base;
  1         1008  
  1         24  
27 1     1   5 use base qw( Class::Base );
  1         4  
  1         180  
28              
29             our $VERSION = '0.01';
30             our $REVISION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
31             our $ERROR;
32              
33              
34             #------------------------------------------------------------------------
35             # init()
36             #------------------------------------------------------------------------
37              
38             sub init {
39 4     4 1 368 my ($self, $config) = @_;
40 4         8 my $class = ref $self;
41              
42 4         18 while (my ($name, $value) = each %$config) {
43 1     1   5 no strict 'refs';
  1         1  
  1         293  
44 14         24 my $type = ref $value;
45            
46 14 100       37 if ($type eq 'CODE') {
    100          
    50          
47 2         3 my $coderef = $value;
48 2         22 *{"$class\::$name"} = sub {
49 4     4   79 my $facade = shift;
50 4         10 &$coderef(@_);
51 2         7 };
52             }
53             elsif ($type eq 'ARRAY') {
54 6         16 my ($object, $method, @args) = @$value;
55 6         50 *{"$class\::$name"} = sub {
56 8     8   107 my $facade = shift;
57 8         29 $object->$method(@args, @_);
58 6         32 };
59             }
60             elsif ($type eq 'HASH') {
61             my $object = $value->{ class }
62             || $value->{ object }
63 6   100     49 || return $self->error("$name: no 'class' or 'object' specified");
64             my $method = $value->{ method }
65 4   50     11 || return $self->error("$name: no 'method' specified");
66 4   50     10 my $args = $value->{ args } || [ ];
67              
68 4         33 *{"$class\::$name"} = sub {
69 8     8   108 my $facade = shift;
70 8         25 $object->$method(@$args, @_);
71 4         16 };
72             }
73             else {
74 0         0 return $self->error("$name: invalid delegate specification");
75             }
76             }
77              
78 2         7 return $self;
79             }
80              
81              
82             1;
83              
84              
85             =head1 NAME
86              
87             Class::Facade - interface to one or more delegates
88              
89             =head1 SYNOPSIS
90              
91             use Class::Facade;
92              
93             my $facade = Class::Facade->new({
94             method1 => sub { ... },
95             method2 => [ $class, $method, $arg1, $arg2, ... ],
96             method3 => [ $object, $method, $arg1, $arg2, ... ],
97             method4 => {
98             class => 'My::Delegate::Class',
99             method => 'method_name',
100             args => [ $arg1, $arg2, ... ],
101             },
102             method5 => {
103             object => $object,
104             method => 'method_name',
105             args => [ $arg1, $arg2, ... ],
106             },
107             });
108              
109             $facade->method1($more_args1, ...);
110             $facade->method2($more_args2, ...);
111             # ...etc...
112              
113             =head1 DESCRIPTION
114              
115             This module implements a simple facade class, allowing you to create
116             objects that delegate their methods to subroutines or other object or
117             class methods.
118              
119             To create a delegate object, simply call the new() constructor passing a
120             reference to a hash array describing the methods and their delegates.
121             Each key in the hash specifies a method name for your facade object.
122             Each value specifies the delegate target and should be a reference to
123             a subroutine, list or hash array.
124              
125             In the case of a list, the elements in the list should be a class name
126             or object reference followed by a method name and a list of any
127             arguments that you want passed to the method when it is called. Any
128             additional arguments that the caller of the facade method specifies will
129             also be passed.
130              
131             In the case of a hash, the C or C element specifies a
132             class name or object references, the C element names the
133             class/object method to be called and C is an optional reference
134             to a list of arguments as above.
135              
136             The Class::Facade constructor creates accessor methods in the module's
137             symbol table. One important side effect of this is that all methods
138             defined will be created for all object of the same class. For this
139             reason it is recommended that you create your own facade modules which
140             are subclass from Class::Facade.
141              
142             package My::Facade::One;
143             use base qw( Class::Facade );
144              
145             package My::Facade::Two;
146             use base qw( Class::Facade );
147              
148             package main;
149             my $one = My::Facade::One->new({ ... });
150             my $two = My::Facade::Two->new({ ... });
151              
152             =head1 AUTHOR
153              
154             Andy Wardley Eabw@kfs.orgE
155              
156             =head1 COPYRIGHT
157              
158             Copyright (C) 2001-2002 Andy Wardley. All Rights Reserved.
159              
160             This module is free software; you can redistribute it and/or
161             modify it under the same terms as Perl itself.
162              
163             =cut