Decorator
Version 2.x
Decorator is a function that can transform/augment objects, classes, or methods dynamically adding new functionality to them. Decorator is a useful tool of meta-programming, and used extensively in different programming languages.
dcl
uses method decorators so we will concentrate on them.
Concept
In general a method decorator is a function that receives a function, optional parameters, and return a new function (or the same but updated). The goal is to modify its behavior in a predictable generic way. So essentially a decorator looks like that:
1 2 3 4 5 6 7 |
|
Examples
Transaction
Let’s assume that there is a global transaction and we want to implement a simple transaction management for our database-aware functions/methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Tracing
Note: we do not handle exceptions below for simplicity.
1 2 3 4 5 6 7 8 |
|
With this decorator we can trace when a controlled method is called, and if it calls itself recursively directly or indirectly.
Pre- or post-processing
We may want to normalize input or output of a function in a predictable way. A postprocessing example, which converts non-string objects to JSON:
1 2 3 4 5 6 7 8 |
|
Now we can build on this functionality. For example, we can add a JSONP callback, if it is requested in parameters:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Similarly we can add different formatters, like XML, and so on. The important idea here is that we can do it orthogonally in one place.
Decorators in dcl
While dcl
can work with classic method decorators, decorators for supercalls, or advices do not return a function. Instead they return an object with meta-information, which is used later to assemble objects producing required functions and methods.
All such objects are based on dcl.Super.
Now if you see a code like this:
1 2 3 4 5 6 7 8 9 10 |
|
You know that these are not some magic, but simple functions that communicate to dcl
how you want to assemble objects.