One of my last acts at my current job is writing a server that speaks SOAP and/or XML-RPC. Another developer is writing the client, in Python. I've used XML-RPC before, but hadn't done more than read through the docs for SOAP::Lite (and reviewed a couple of chapters for the upcoming Programming Web Services with Perl book). It's quite impressive, though.
For performance reasons during development, we switched our internal protocol to XML-RPC. Writing a server to handle that was also very quick and easy with SOAP::Lite. Writing a forking server is not difficult, either. Where the Python client is multi-threaded, I'm using multi processes as Unix intends!
Since several users can use the application at the same time, we're implementing access controls. Different user accounts exist, with different permissions. Some accounts only have read access, others can update, and still others can delete.
I like the way SOAP::Lite automatically dispatches requests to a specified package, but building in access controls to every method is too much work.
I created a proxy object (and not in the Matt Sergeant sense) to which SOAP::Lite autodispatches. The real work is done in the server object. The proxy object actually implements the access controls, creating user sessions, checking magic cookies, and testing if the user has the proper credentials to perform each operation.
The remaining issue was to identify the accessable methods in the server object and to mark them with the permissions they need. Maintaining a separate list somewhere struck me as too much work -- I'd have to keep updating code in two places. That's insufficiently lazy.
What I did was to use Attribute::Handlers to create a 'Publish' attribute. Now any method I want to be publicly available needs that attribute. Publish also takes an argument, the necessary permissions. The attribute handler stores the name of the method, a reference to the method, and the permission string. The proxy object calls get_methods(), receiving this data structure. It installs wrappers around each of these methods in the proxy object itself. That way, they're visible to the SOAP::Lite dispatcher, and I only have to resume a user session and check permissions once.
Through this all, I'm pleased to note that my decompisition skills are improving. The Once and Only Once principle really pays off -- if you get in the habit of factoring out common code, it's amazingly easy to add new features. Nearly everything that is reusable is reused.
Finally, a legitimate reason to use attributes and typeglobs in the same program.