digitalmars.D - Simple implementation of __FUNCTION
- Rob T (26/26) Nov 02 2012 Thanks to input from the D community, I've managed to implement a
- Adam D. Ruppe (8/12) Nov 02 2012 template __FUNCTION_SIGNATURE() { const char[]
- Rob T (8/17) Nov 02 2012 That was fast, thanks!
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (8/31) Nov 02 2012 You should totally submit this for inclusion into std.traits in Phobos.
-
Regan Heath
(15/56)
Nov 02 2012
On Fri, 02 Nov 2012 18:06:19 -0000, Alex R=F8nne Petersen
- H. S. Teoh (8/24) Nov 02 2012 [[...]
- mist (4/30) Nov 02 2012 Sweet! You may also find my pull request for phobos ( #863,
- Jacob Carlborg (4/16) Nov 02 2012 That's pretty darn cool, well done :D .
- Philippe Sigaud (14/14) Nov 02 2012 By changing this to a standard function:
- Timon Gehr (3/17) Nov 02 2012 I'd make it
- Rob T (20/35) Nov 02 2012 That looks better. Not sure what the down side would be if any.
- Rob T (5/23) Nov 02 2012 No luck with enum version, it still fails to compile when used
- Jacob Carlborg (4/21) Nov 03 2012 I think it would be worth to but in Phobos anyway.
- Rob T (5/6) Nov 03 2012 I suppose it works as a temp solution until a real one is finally
- Rob T (8/26) Nov 05 2012 An update on this problem. I found out that the error when using
- Don Clugston (14/47) Nov 05 2012 It fails because you're asking for the full function name, before its
- Simen Kjaeraas (16/29) Nov 06 2012 DMD already does some cycle detection for types, right? I don't remember
- r_m_r (25/81) Nov 06 2012 I don't know how I missed this thread. I was having the same
- Rob T (6/9) Nov 06 2012 In our case, the function name that is returned is nothing but
- Jonathan M Davis (5/27) Nov 02 2012 Identifiers starting with __ are reserved for the compiler/language. It ...
- Philippe Sigaud (5/9) Nov 02 2012 Er, yes, but __FUNCTION comes the OP. My question was more about using
Thanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function. This is used for basic execution monitoring and for automated logging of exception errors. Here's what I did. template __FUNCTION() { const char[] __FUNCTION = "__traits(identifier, __traits(parent, {}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ ); The ONLY thing left that I would like to have, is ability to display the function signature along with the name. The signature will be very useful to show which version of an overloaded or templated function was called. If anyone can suggest imporvements, like how to get rid of need to explicitly call mixin, and better yet a solution to get the function signature, please post away. Thanks! I have to mention that we need a real solution that can only be provided through improved reflection support, eg __scope.function, __scope.line, __scope.file, etc, or whatever the D community thinks will fit in best. --rt
Nov 02 2012
On Friday, 2 November 2012 at 17:31:55 UTC, Rob T wrote:Thanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function.Huh, that's pretty brilliant!The ONLY thing left that I would like to have, is ability to display the function signature along with the name.template __FUNCTION_SIGNATURE() { const char[] __FUNCTION_SIGNATURE = "typeof(__traits(parent, {})).stringof"; } int main(string[] args) { assert(0, mixin(__FUNCTION_SIGNATURE!())); } core.exception.AssertError test4.d(7): int(string[] args)
Nov 02 2012
On Friday, 2 November 2012 at 17:55:33 UTC, Adam D. Ruppe wrote:That was fast, thanks! template __PRETTY_FUNCTION() { const char[] __PRETTY_FUNCTION = "__traits(identifier, __traits(parent, {})) ~ " ~ __FUNCTION_SIGNATURE!(); } --rtThe ONLY thing left that I would like to have, is ability to display the function signature along with the name.template __FUNCTION_SIGNATURE() { const char[] __FUNCTION_SIGNATURE = "typeof(__traits(parent, {})).stringof"; } int main(string[] args) { assert(0, mixin(__FUNCTION_SIGNATURE!())); } core.exception.AssertError test4.d(7): int(string[] args)
Nov 02 2012
On 02-11-2012 18:31, Rob T wrote:Thanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function. This is used for basic execution monitoring and for automated logging of exception errors. Here's what I did. template __FUNCTION() { const char[] __FUNCTION = "__traits(identifier, __traits(parent, {}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ ); The ONLY thing left that I would like to have, is ability to display the function signature along with the name. The signature will be very useful to show which version of an overloaded or templated function was called. If anyone can suggest imporvements, like how to get rid of need to explicitly call mixin, and better yet a solution to get the function signature, please post away. Thanks! I have to mention that we need a real solution that can only be provided through improved reflection support, eg __scope.function, __scope.line, __scope.file, etc, or whatever the D community thinks will fit in best. --rtYou should totally submit this for inclusion into std.traits in Phobos. (Though, to follow naming conventions, it should be functionName and functionSignature or so.) -- Alex Rønne Petersen alex lycus.org http://lycus.org
Nov 02 2012
On Fri, 02 Nov 2012 18:06:19 -0000, Alex R=F8nne Petersen <alex lycus.or= g> = wrote:On 02-11-2012 18:31, Rob T wrote:rThanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function. This is used fo=basic execution monitoring and for automated logging of exception =, =errors. Here's what I did. template __FUNCTION() { const char[] __FUNCTION =3D "__traits(identifier, __traits(parent=the{}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ ); The ONLY thing left that I would like to have, is ability to display =asfunction signature along with the name. The signature will be very useful to show which version of an overloaded or templated function w=dedcalled. If anyone can suggest imporvements, like how to get rid of need to explicitly call mixin, and better yet a solution to get the function signature, please post away. Thanks! I have to mention that we need a real solution that can only be provi=e,through improved reflection support, eg __scope.function, __scope.lin=t.__scope.file, etc, or whatever the D community thinks will fit in bes=.--rtYou should totally submit this for inclusion into std.traits in Phobos=(Though, to follow naming conventions, it should be functionName and =functionSignature or so.)+1 :) R -- = Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 02 2012
On Fri, Nov 02, 2012 at 07:06:19PM +0100, Alex Rønne Petersen wrote:On 02-11-2012 18:31, Rob T wrote:[...][[...]template __FUNCTION() { const char[] __FUNCTION = "__traits(identifier, __traits(parent, {}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ );You should totally submit this for inclusion into std.traits in Phobos. (Though, to follow naming conventions, it should be functionName and functionSignature or so.)[...] +1. T -- Тише едешь, дальше будешь.
Nov 02 2012
fullyQualifiedTypename ) useful for adding function signature once it gets finalised and merged. On Friday, 2 November 2012 at 17:31:55 UTC, Rob T wrote:Thanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function. This is used for basic execution monitoring and for automated logging of exception errors. Here's what I did. template __FUNCTION() { const char[] __FUNCTION = "__traits(identifier, __traits(parent, {}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ ); The ONLY thing left that I would like to have, is ability to display the function signature along with the name. The signature will be very useful to show which version of an overloaded or templated function was called. If anyone can suggest imporvements, like how to get rid of need to explicitly call mixin, and better yet a solution to get the function signature, please post away. Thanks! I have to mention that we need a real solution that can only be provided through improved reflection support, eg __scope.function, __scope.line, __scope.file, etc, or whatever the D community thinks will fit in best. --rt
Nov 02 2012
On 2012-11-02 18:31, Rob T wrote:Thanks to input from the D community, I've managed to implement a reasonable way to log the name of a calling function. This is used for basic execution monitoring and for automated logging of exception errors. Here's what I did. template __FUNCTION() { const char[] __FUNCTION = "__traits(identifier, __traits(parent, {}))"; } Example use in code: throw new Exception( "Error: Function ", mixin(__FUNCTION!()) ); writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION!()), __LINE__ );That's pretty darn cool, well done :D . -- /Jacob Carlborg
Nov 02 2012
By changing this to a standard function: const(char[]) __FUNCTION() property { return "__traits(identifier, __traits(parent, {}))"; } ... the calling syntax is slightly easier on the eye: void main() { writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION), __LINE__ ); //throw new Exception( "Error: Function " ~ mixin(__FUNCTION) ); } That is, mixin(__FUNCTION) instead of mixin(__FUNCTION!()) Is there any downside to this?
Nov 02 2012
On 11/02/2012 10:34 PM, Philippe Sigaud wrote:By changing this to a standard function: const(char[]) __FUNCTION() property { return "__traits(identifier, __traits(parent, {}))"; } ... the calling syntax is slightly easier on the eye: void main() { writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION), __LINE__ ); //throw new Exception( "Error: Function " ~ mixin(__FUNCTION) ); } That is, mixin(__FUNCTION) instead of mixin(__FUNCTION!()) Is there any downside to this?I'd make it enum currentFunction = q{ __traits(identifier, __traits(parent, {})) };
Nov 02 2012
On Friday, 2 November 2012 at 21:34:23 UTC, Philippe Sigaud wrote:By changing this to a standard function: const(char[]) __FUNCTION() property { return "__traits(identifier, __traits(parent, {}))"; } ... the calling syntax is slightly easier on the eye: void main() { writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION), __LINE__ ); //throw new Exception( "Error: Function " ~ mixin(__FUNCTION) ); } That is, mixin(__FUNCTION) instead of mixin(__FUNCTION!()) Is there any downside to this?That looks better. Not sure what the down side would be if any. Unrelated to either form, I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved. I'll try the enum idea to see if that works. --rt
Nov 02 2012
On Friday, 2 November 2012 at 22:33:37 UTC, Rob T wrote:Unrelated to either form, I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved. I'll try the enum idea to see if that works. --rtNo luck with enum version, it still fails to compile when used inside a function with auto as the return type, same "forward reference" error. --rt
Nov 02 2012
On 2012-11-02 23:33, Rob T wrote:That looks better. Not sure what the down side would be if any. Unrelated to either form, I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved.I think it would be worth to but in Phobos anyway. -- /Jacob Carlborg
Nov 03 2012
On Saturday, 3 November 2012 at 11:09:48 UTC, Jacob Carlborg wrote:I think it would be worth to but in Phobos anyway.I suppose it works as a temp solution until a real one is finally implemented, or maybe the mixin behaviour is considered a bug and can be fixed?
Nov 03 2012
On Saturday, 3 November 2012 at 17:04:31 UTC, Rob T wrote:On Saturday, 3 November 2012 at 11:09:48 UTC, Jacob Carlborg wrote:I think __FUNCTION__ should be built into the compiler, with it's brothers __FILE__ and __LINE__ . This kinda thing is so useful while debugging and logging :)I think it would be worth to but in Phobos anyway.I suppose it works as a temp solution until a real one is finally implemented, or maybe the mixin behaviour is considered a bug and can be fixed?
Nov 04 2012
On Sunday, 4 November 2012 at 13:57:07 UTC, Damian wrote:On Saturday, 3 November 2012 at 17:04:31 UTC, Rob T wrote:I completely agree. Direct compiler support is the only way to implement this form of reflection reliably for all cases. Also consider that with D we have an opportunity to implement reflection features in a more consistent way through a generlized form of reflection. --rtOn Saturday, 3 November 2012 at 11:09:48 UTC, Jacob Carlborg wrote:I think __FUNCTION__ should be built into the compiler, with it's brothers __FILE__ and __LINE__ . This kinda thing is so useful while debugging and logging :)I think it would be worth to but in Phobos anyway.I suppose it works as a temp solution until a real one is finally implemented, or maybe the mixin behaviour is considered a bug and can be fixed?
Nov 04 2012
On Friday, 2 November 2012 at 22:33:37 UTC, Rob T wrote:I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved. I'll try the enum idea to see if that works. --rtAn update on this problem. I found out that the error when using auto as return type has nothing to do with the mixin. The compiler error persists when you take mixin out and put in the __traits( ... ) code directly. Does anyone else think that this is a compiler bug? If it is a bug then I'll report it in the bug tracker. --rt
Nov 05 2012
On 06/11/12 07:09, Rob T wrote:On Friday, 2 November 2012 at 22:33:37 UTC, Rob T wrote:It fails because you're asking for the full function name, before its type has been determined. (There's no real return type 'auto', 'auto' just means 'work it out for me'). I don't think this is a bug. Although it might be solvable in this particular example, in general it's a circular dependency. eg, if you do: auto foo() { static if (__FUNCTION == "int foo()") { return 'a' } return 0; } if __FUNCTION is "int foo()" then it will return a char, which means its signature is "char foo()". This is a contradiction.I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved. I'll try the enum idea to see if that works. --rtAn update on this problem. I found out that the error when using auto as return type has nothing to do with the mixin. The compiler error persists when you take mixin out and put in the __traits( ... ) code directly. Does anyone else think that this is a compiler bug? If it is a bug then I'll report it in the bug tracker. --rt
Nov 05 2012
On 2012-46-06 08:11, Don Clugston <dac nospam.com> wrote:It fails because you're asking for the full function name, before its type has been determined. (There's no real return type 'auto', 'auto' just means 'work it out for me'). I don't think this is a bug. Although it might be solvable in this particular example, in general it's a circular dependency. eg, if you do: auto foo() { static if (__FUNCTION == "int foo()") { return 'a' } return 0; } if __FUNCTION is "int foo()" then it will return a char, which means its signature is "char foo()". This is a contradiction.DMD already does some cycle detection for types, right? I don't remember the details, but i seem to recall this was made to work a few releases back: class Foo { static if ( is( typeof( Foo.bar ) ) ) { void baz() {} } static if ( true ) { int bar() {} } } The algorithm would probably have to exclude mixins, but I think it could be made to work for most cases. -- Simen
Nov 06 2012
I don't know how I missed this thread. I was having the same 'forward reference' error and after a brief chat on #D IRC, thought it might be a compiler bug and reported it as such: http://d.puremagic.com/issues/show_bug.cgi?id=8963 . Should I close this issue? Any thoughts on possible workarounds? BTW I've been 'mixing'-in this template in all my functions (for debugging): //---- Code --- import std.traits : PIT=ParameterIdentifierTuple; template dbg(string msg) { const char[] dbg = "writeln( src(\"DBG\", __traits(identifier, __traits(parent, {})) ~ _params_join([PIT!(__traits(parent,{}))]), " ~ msg ~ " ) );" ; } //----- Code --- Its working great except for the "auto"-return functions. rmr On Tuesday, 6 November 2012 at 07:46:47 UTC, Don Clugston wrote:On 06/11/12 07:09, Rob T wrote:On Friday, 2 November 2012 at 22:33:37 UTC, Rob T wrote:It fails because you're asking for the full function name, before its type has been determined. (There's no real return type 'auto', 'auto' just means 'work it out for me'). I don't think this is a bug. Although it might be solvable in this particular example, in general it's a circular dependency. eg, if you do: auto foo() { static if (__FUNCTION == "int foo()") { return 'a' } return 0; } if __FUNCTION is "int foo()" then it will return a char, which means its signature is "char foo()". This is a contradiction.I discovered it fails to compile when inside a function with "auto" as the return type. auto test() { throw new Exception( mixin(__FUNCTION) ); return 0; } Error: forward reference to test but this works int test() { throw new Exception( mixin(__FUNCTION) ); return 0; } So we're kinda sunk for inclusion in phobos unless this error can be resolved. I'll try the enum idea to see if that works. --rtAn update on this problem. I found out that the error when using auto as return type has nothing to do with the mixin. The compiler error persists when you take mixin out and put in the __traits( ... ) code directly. Does anyone else think that this is a compiler bug? If it is a bug then I'll report it in the bug tracker. --rt
Nov 06 2012
On Tuesday, 6 November 2012 at 07:46:47 UTC, Don Clugston wrote:It fails because you're asking for the full function name, before its type has been determined. (There's no real return type 'auto', 'auto' just means 'work it out for me').In our case, the function name that is returned is nothing but the function's symbol name by itself, which of course is known ahead of time no matter if auto is stated or not. This is why it seems more like a bug to me. --rt
Nov 06 2012
On Friday, November 02, 2012 22:34:15 Philippe Sigaud wrote:By changing this to a standard function: const(char[]) __FUNCTION() property { return "__traits(identifier, __traits(parent, {}))"; } ... the calling syntax is slightly easier on the eye: void main() { writefln( "File: %s, Func: %s, Line: %d", __FILE__, mixin(__FUNCTION), __LINE__ ); //throw new Exception( "Error: Function " ~ mixin(__FUNCTION) ); } That is, mixin(__FUNCTION) instead of mixin(__FUNCTION!()) Is there any downside to this?Identifiers starting with __ are reserved for the compiler/language. It should be __FUNCTION__ if it's built-in, but if it's in the library, I see no reason to name it in a way that conflicts with Phobos' naming conventions like this. - Jonathan M Davis
Nov 02 2012
On Fri, Nov 2, 2012 at 10:59 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Er, yes, but __FUNCTION comes the OP. My question was more about using a function instead of a template. And Timon makes a good point, using a token string q{ } should make this more mixin-able.Is there any downside to this?Identifiers starting with __ are reserved for the compiler/language. It should be __FUNCTION__ if it's built-in, but if it's in the library, I see no reason to name it in a way that conflicts with Phobos' naming conventions like this.
Nov 02 2012