request: python style decorators / aspect orientation
Chris Nicholson-Sauls
ibisbasenji at gmail.com
Thu May 10 00:14:42 PDT 2007
Daniel Keep wrote:
>
> Nicolai Waniek wrote:
>> Hi everyone,
>>
>> Hopefully a few of you knew the python style decorators (python's version of
>> aspect orientation):
>>
>>
>> def aspectFunc(f):
>> def wrapper():
>> print "log before function call"
>> f()
>> print "log after function call"
>>
>> return wrapper
>>
>> @aspecFunc
>> def myfunction():
>> print "hello world"
>>
>>
>> Would it be possible to have something like this in D? IMHO it would make code
>> more clear. For example it could look like this when decorating a function:
>>
>>
>> version (debug) {
>> @logFunc
>> }
>> void myFunction(int param0)
>> {
>> // do something here
>> }
>>
>>
>> instead of:
>>
>> void myFunction(int param0)
>> {
>> version (debug) {
>> logthis("blabla");
>> }
>> // do something here
>> version (debug) {
>> logthis("finally we reached an end here");
>> }
>> }
>>
>> I think it would take all the bloat out of functions that doesn't really belong
>> to the function. I don't know how much work it would be to implement such a
>> thing, but I think there would be many cases this could be usefull. If this is
>> already possible in a sane way, please let me know as this is one of the
>> features I do like most in python and would like to have in D.
>>
>> Best regards,
>> Nicolai
>
> This is just a quick hack, but it does work. The main problem is that
> you have to put the logFunc alias *after* the function is defined, or
> you get forward-reference errors.
>
> Apart from that, it should do what you want.
>
> -- Daniel
>
> -----
>
> module fnwrap;
>
> import std.stdio;
> import std.traits;
>
> void logthis(char[] msg)
> {
> writefln("LOG - %s", msg);
> }
>
> ReturnType!(typeof(fn)) logFunc(alias
> fn)(ParameterTypeTuple!(typeof(fn)) args)
> {
> alias ReturnType!(typeof(fn)) returnT;
> debug
> {
> logthis("ENTER - "~(&fn).stringof);
> scope(exit) logthis("EXIT - "~(&fn).stringof);
> }
> static if( is( returnT == void ) )
> fn(args);
> else
> return fn(args);
Actually you can leave this check out, as I recall. Returning values in void-return
functions is allowed, and I would infer (haven't tested, however) that returning a void
from a void() would also be fine. Could be wrong.
> }
>
> void myFunction_(int param0)
> {
> writefln("Do something with %s...", param0);
> }
> alias logFunc!(myFunction_) myFunction;
>
> void main()
> {
> myFunction(42);
> }
>
Overall a neat and useful trick.
-- Chris Nicholson-Sauls
More information about the Digitalmars-d
mailing list