Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 02, 2012 Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
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 |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | 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) |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | 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. > > --rt > > 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.) -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Fri, 02 Nov 2012 18:06:19 -0000, Alex Rønne Petersen <alex@lycus.org> wrote: > 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. >> >> --rt >> >> > > 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 :) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | 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 -- Тише едешь, дальше будешь. |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | Sweet! You may also find my pull request for phobos ( #863, 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
|
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | 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 |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Friday, 2 November 2012 at 17:55:33 UTC, Adam D. Ruppe wrote:
>> 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)
That was fast, thanks!
template __PRETTY_FUNCTION()
{
const char[] __PRETTY_FUNCTION = "__traits(identifier, __traits(parent, {})) ~ " ~ __FUNCTION_SIGNATURE!();
}
--rt
|
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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? |
November 02, 2012 Re: Simple implementation of __FUNCTION | ||||
---|---|---|---|---|
| ||||
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
|
Copyright © 1999-2021 by the D Language Foundation