Thread overview |
---|
June 24, 2017 Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
The code: alias Response = Nullable!(string, "empty response (error)"); Response processMessage(string commandModule)(string message, bool isCommand) { import std.meta; import std.string; import std.traits; import command_uda; mixin("import " ~ commandModule ~ ';'); bool foundCommandMatch = false; foreach(symbol; getSymbolsByUDA!(mixin(commandModule), Command)) { enum commandUDA = getUDAs!(symbol, Command)[0]; auto commandPhrase = commandUDA.phrase == "" ? symbol.stringof : commandUDA.phrase; //Error: function <function signature> is not callable using argument types () auto commandPhrasePattern = regex(`^%s\s`.format(commandPhrase)); if (message.matchFirst(commandPhrasePattern) && !foundCommandMatch) { version(responseDebug) writeln("Matched command ", symbol.stringof, " with phrase '", commandPhrase, "'\n"); //Same issue return Response(symbol(message.strip())); } } return Response.init; } I've been banging my head against this and cannot figure out why `symbol.stringof` is being called instead of getting a string of the symbol. I tried to create a reduced test case but it works fine: import std.stdio; import std.traits; enum Attr; @Attr string test1() { return __FUNCTION__; } @Attr string test2() { return __FUNCTION__; } void process() { foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr)) { writeln("The result of calling ", symbol.stringof, " is ", symbol()); } } void main() { process(); } So I have no clue what I'm doing wrong. This is driving me insane. |
June 24, 2017 Re: Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | Meta wrote:
> So I have no clue what I'm doing wrong. This is driving me insane.
aaaah. known $#^#$@^@%.
enum SymName = (&symbol).stringof[2..$]; // this, instead of symbol.stringof
dirty hack, let's hope that DMD devs won't change `.toString()` output (i.e. first two chars will always be "& ").
besides this, i know no other way to stop compiler from calling the function there.
|
June 24, 2017 Re: Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | ketmar wrote:
> `.toString()`
toChars().
;-)
|
June 24, 2017 Re: Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | ketmar wrote:
> Meta wrote:
>
>> So I have no clue what I'm doing wrong. This is driving me insane.
>
> aaaah. known $#^#$@^@%.
>
> enum SymName = (&symbol).stringof[2..$]; // this, instead of symbol.stringof
>
> dirty hack, let's hope that DMD devs won't change `.toString()` output (i.e. first two chars will always be "& ").
>
> besides this, i know no other way to stop compiler from calling the function there.
i hope devs won't break string representation: i bet that there is ALOT of code that is using this trick. i myself borrowed it from some other module several years ago. and it looks that the module where i found it borrowed the trick from some another module. a really long history. ;-)
|
June 24, 2017 Re: Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On 6/24/17 3:53 AM, Meta wrote: > The code: > > alias Response = Nullable!(string, "empty response (error)"); > > Response processMessage(string commandModule)(string message, bool isCommand) > { > import std.meta; > import std.string; > import std.traits; > > import command_uda; > > mixin("import " ~ commandModule ~ ';'); > bool foundCommandMatch = false; > foreach(symbol; getSymbolsByUDA!(mixin(commandModule), Command)) > { > enum commandUDA = getUDAs!(symbol, Command)[0]; > auto commandPhrase = commandUDA.phrase == "" ? symbol.stringof : commandUDA.phrase; //Error: function <function signature> is not callable using argument types () > auto commandPhrasePattern = regex(`^%s\s`.format(commandPhrase)); > if (message.matchFirst(commandPhrasePattern) && !foundCommandMatch) > { > version(responseDebug) writeln("Matched command ", symbol.stringof, " with phrase '", commandPhrase, "'\n"); //Same issue > return Response(symbol(message.strip())); > } > } > > return Response.init; > } > > I've been banging my head against this and cannot figure out why `symbol.stringof` is being called instead of getting a string of the symbol. I tried to create a reduced test case but it works fine: > > import std.stdio; > import std.traits; > > enum Attr; > > @Attr string test1() { return __FUNCTION__; } > @Attr string test2() { return __FUNCTION__; } > > void process() > { > foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr)) > { > writeln("The result of calling ", symbol.stringof, " is ", symbol()); > } > } > > void main() > { > process(); > } > > So I have no clue what I'm doing wrong. This is driving me insane. I know what you are doing wrong in your reduced case. Try this instead: @Attr string test1(int) { return __FUNCTION__; } @Attr string test2(int) { return __FUNCTION__; } void process() { foreach (symbol; getSymbolsByUDA!(mixin(__MODULE__), Attr)) { writeln("The result of calling ", symbol.stringof, " is ", symbol(1)); } } The reason your version "works" is because your functions actually are callable with no args! I tried many things including: enum symbolname = symbol.stringof; enum symbolname = (symbol).stringof; pragma(msg, symbol.stringof); Nothing works. If this isn't already a bug, you should file it. Aside from ketmar's workaround, I can't think of one. It's interesting that the ability to call without parentheses is what causes the error, yet when you *can* call without parentheses, it doesn't actually do so (symbol.stringof prints the name of the symbol). This seems very obviously to be a bug. -Steve |
June 24, 2017 Re: Help me escape optional parens hell | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 24 June 2017 at 08:08:33 UTC, ketmar wrote: > Meta wrote: > >> So I have no clue what I'm doing wrong. This is driving me insane. > > aaaah. known $#^#$@^@%. > > enum SymName = (&symbol).stringof[2..$]; // this, instead of symbol.stringof > > dirty hack, let's hope that DMD devs won't change `.toString()` output (i.e. first two chars will always be "& "). > > besides this, i know no other way to stop compiler from calling the function there. It's dirty but I guess I'll have to go with this hack for the time being. Also, I filed a bug: https://issues.dlang.org/show_bug.cgi?id=17546 |
Copyright © 1999-2021 by the D Language Foundation