digitalmars.D.learn - Help me escape optional parens hell
- Meta (53/53) Jun 24 2017 The code:
- ketmar (6/7) Jun 24 2017 aaaah. known $#^#$@^@%.
- ketmar (3/4) Jun 24 2017 toChars().
- ketmar (5/14) Jun 24 2017 i hope devs won't break string representation: i bet that there is ALOT ...
- Meta (5/15) Jun 24 2017 It's dirty but I guess I'll have to go with this hack for the
- Steven Schveighoffer (25/86) Jun 24 2017 I know what you are doing wrong in your reduced case. Try this instead:
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.
Jun 24 2017
Meta wrote:So I have no clue what I'm doing wrong. This is driving me insane.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.
Jun 24 2017
ketmar wrote:Meta wrote: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. ;-)So I have no clue what I'm doing wrong. This is driving me insane.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.
Jun 24 2017
On Saturday, 24 June 2017 at 08:08:33 UTC, ketmar wrote:Meta wrote: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=17546So I have no clue what I'm doing wrong. This is driving me insane.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.
Jun 24 2017
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
Jun 24 2017









ketmar <ketmar ketmar.no-ip.org> 