request: python style decorators / aspect orientation

Daniel Keep daniel.keep.lists at gmail.com
Wed May 9 21:24:49 PDT 2007



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);
}

void myFunction_(int param0)
{
    writefln("Do something with %s...", param0);
}
alias logFunc!(myFunction_) myFunction;

void main()
{
    myFunction(42);
}

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/



More information about the Digitalmars-d mailing list