GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
WWW::Mechanize::Pluggable::Design(3) User Contributed Perl Documentation WWW::Mechanize::Pluggable::Design(3)

WWW::Mechanize::Pluggable::Design - the architecture of WWW::Mechanize::Pluggable

This document describes "WWW::Mechanize::Pluggable"'s design and explains how it works, including plugins and how they interact with the base module.

Previous to the creation of "WWW::Mechanize::Pluggable", anyone who wanted an extended version of "WWW::Mechanize" had to subclass it to add new features.

This in itself is not a bad thing: many modules have been created to address specific behaviors that "WWW::Mechanize" doesn't support itself:

"WWW::Mechanize::Sleepy" - pauses between requests
"WWW::Mechanize::Cached" - caches requests
"WWW::Mechanize::Timed" - times requests

And so on. The problem is, what if you want both the "Sleepy" behavior and the "Cached" behavior simultaneously? The answer is you can't do that unless you write a module which inherits from both.

This approach isn't viable in the long term because the number of possible combinations of behavior grows too fast. So how can we address this problem?

A partial solution comes from "Module::Pluggable". This module allows you to create plugins - specially-named packages, installed just like regular modules. A base package, which uses "Module::Pluggable", can then automatically search for and load extra functions via these plugin classes.

This solves the problem of extending a base class - if you're the one who controls the base class's source code.

The simplest way to solve the problem is just to create a subclass of the class you want to add plugin functionality to - in our case, "WWW::Mechanize" - and then write plugins. And as long as all you're doing is just adding new functions, you're in good shape.

But what if you want to change the way something functions, rather than just add something new? You have a problem, because a plugin can't do that - or rather, two different plugins that want to alter the same base-class method can't do so without knowing about each other. This might seem like a good-enough solution, but it has the same problem as the "subclass the subclasses" approach: you have a combinatorial explosion of checks that have to be made every time a new module that wants to alter the same base-class method gets into the act.

The approach used in "WWW::Mechanize::Pluggable" is to combine the proxy pattern (one class intercepts all the calls for another and then passes them on) and the decorator pattern (one class instantiates another, then exposes methods matching all of the second classes methods, with its own code inserted before and/or after the calls to the contained class).

Perl provides us with very flexible ways to deal with this process.

AUTOLOAD

We use "AUTOLOAD" to "catch" all the calls to the class. We actually implement very little in "WWW::Mechanize::Pluggable"; only enough to be able to create the base object and its contained "WWW::Mechanize" object.

To decorate, we add a hash of pre-hook and post-hook lists. These are subroutines to be called before (pre-hook) and after (post-hook) the base-class methods. Now it's possible to alter either the behavior of a given method, or to feed it different parameters "behind the back" of the main program.

We'll speak specifically about "WWW::Mechanize::Pluggable" here; wo hope to extract the "pluggability" into a completely separate module in the very near future, allowing the creation of "::Pluggable" versions of any module you please.

2019-02-01 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.