File: mod_perl_method_handlers.pod

package info (click to toggle)
apache-perl 1.3.9-14.1-1.21.20000309-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 5,524 kB
  • ctags: 1,743
  • sloc: ansic: 9,017; perl: 7,822; sh: 864; makefile: 695
file content (183 lines) | stat: -rw-r--r-- 4,781 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

=head1 NAME 

mod_perl_method_handlers - How to use mod_perl's MethodHandlers 

=head1 DESCRIPTION

Described here are a few examples and hints how to use MethodHandlers
with modperl.

This document assumes familiarity with at least L<perltoot> and
"normal" usage of the Perl*Handlers.

It isn't strictly modperl related, more like "what I use objects for
in my modperl environment".

=head1 SYNOPSIS

If a Perl*Handler is prototyped with '$$', this handler will be
invoked as method, being passed a class name or blessed object as its
first argument and the blessed I<request_rec> as the second argument,
e.g.

 package My;
 @ISA = qw(BaseClass);

 sub handler ($$) {
     my($class, $r) = @_;
     ...;
 }

 package BaseClass;

 sub method ($$) {
     my($class, $r) = @_;
     ...;
 }

 __END__

Configuration:

 PerlHandler My

or

 PerlHandler My->handler

Since the handler is invoked as a method, it may inherit from other
classes:

 PerlHandler My->method

In this case, the 'My' class inherits this method from 'BaseClass'.

To build in this feature, configure with:

 % perl Makefile.PL PERL_METHOD_HANDLERS=1 [PERL_FOO_HOOK=1,etc]

=head1 WHY?

The short version: For pretty much the same reasons we're using OO
perl everywhere else. :-) See L<perltoot>.

The slightly longer version would include some about code reusage and
more clean interface between modules.

=head1 SIMPLE EXAMPLE

Let's start with a simple example.

In httpd.conf:

 <Location /obj-handler>
 SetHandler perl-script
 PerlHandler $My::Obj->method
 </Location>

In startup.pl or another PerlRequire'd file:

 package This::Class;

 $My::Obj = bless {};

 sub method ($$) {
     my($obj, $r) = @_;
     $r->send_http_header("text/plain");
     print "$obj isa ", ref($obj);
     0;
 }

which displays:

 This::Class=HASH(0x8411edc) isa This::Class

=head1 A LITTLE MORE ADVANCED

That wasn't really useful, so let's try something little more advanced.

I've a little module which creates a graphical 'datebar' for a client.
(See C<http://www.hip.dk/date_bar>). It's reading a lot of small gifs 
with numbers and weekdays, and keeping them in memory in GD.pm's native 
format, ready to be copied together and served as gifs.

Now I wanted to use it at another site too, but with a different
look. Obviously something to do with a object. Hence I changed the
module to a object, and can now do a 

 $Client1::Datebar = new Datebar(
	 -imagepath => '/home/client1/datebar/',
	 -size      => [131,18],
	 -elements  => 'wday mday mon year hour min',
 );

 $Client2::Datebar = new Datebar
	 -imagepath => '/home/client2/datebar/',
	 -size      => [90,14],
	 -elements  => 'wday hour min',
 );

And then use $Client1::Datebar and $Client2::Datebar as PerlHandlers in my
Apache configuration. Remember to pass them in literal quotes ('') and not
"" which will be interpolated!

I've a webinterface system to our content-database. I've created
objects to handle the administration of articles, banners, images and
other content.  It's then very easy (a few lines of code) to enable
certain modules for each client, depending on their needs.

Another area where I use objects with great success in my modperl
configurations is database abstraction.  All our clients using the
webinterface to handle f.x. articles will use a simple module to
handle everything related to the database.  Each client have

 $Client::Article = new WebAjour::Article(-host => 'www.client.com');

in a module what will be run at server startup.

I can then use some simple methods from the $Client::Article object in
my embperl documents, like:

 [- $c = $Client::Article->GetCursor(-layout=>'Frontpage') -]
 [$ while($c->Fetch) $]
   <h2>[+ $c->f('header') +]</h2>
   [+ $c->f('textfield') +]
 [$ endwhile $]

Very very useful!

=head1 TRAPS

mod_perl expects object handlers to be in the form of a string, which it
will thaw for you. That means that something like 

 $r->push_handlers(PerlHandler => '$self->perl_handler_method');

This doesn't work as you might expect, since Perl isn't able to see
$self once it goes to PerlHandler. 

The best solution to this is to use an anonymous subroutine and pass it $r
yourself, like this:

 $r->push_handlers(PerlHandler => 
     sub {
         my $r = shift;
         $self->perl_handler_method($r);
     }
 );

=head1 AUTHOR

This document is written by Ask Bjoern Hansen <ask@netcetera.dk> or
<ask@apache.org>.  Corrections and suggestions are most
welcome. In particular would more examples be appreciated, most of my
own code is way too integrated with our system, which isn't suitable
for public release.

Some codesnippets is from Doug MacEachern.

=head1 SEE ALSO

L<mod_perl>, L<Apache>, L<perltoot> (also available at
C<http://www.perl.com/CPAN/doc/FMTEYEWTK/perltoot.html>)