Reply to Christopher,
Andrei Alexandrescu wrote:
Cool! I suggest the rewrite:
c.unknownmethod(args) -> c.opDotExp!("unknownmethod")(args)
That way you have the option of handling the method name statically
or dynamically.
How would that allow you to handle the method name dynamically, if
you're passing it as a template argument?
You mean that the *callee* can be dynamic. However, the *caller*
cannot. This would rarely be an issue, I grant, but:
the caller *can't* be dynamic, the calling code is known exactly at compile
time. If you want to be able to call a function by name or by the normal
syntax use:
void CallByName(char[] name, args...) {...}
void opDot(char[] name)(args...) { CallByName(name, args ...); } // one line,
will get inlined if anything ever does.
Let's say you have a set of valid arguments for the opDotExp template.
Why the hell aren't you writing individual methods?!
for one:
struct S(T)
{
T* t;
void opDot!(char[] name)(U u)
{
mixin("t." ~name~ "(v);");
}
}
also haveing a large set of function where you can compute the meaning from
the name:
void Foo(){...}
void FooBar(){...}
void Bar(){...}
//LogFoo
//LogFooBar
//LogBar
void opDot(char[] name)()
{
static assert(name.length > 3 && name[0..3] == "Log")
writelf("Calling "~ name[3..$]);
mixin(name[3..$]~"();");
writelf("Called "~ name[3..$]);
}
So opDotExp is nearly useless if you make the method name a template
argument. The *only* uses are
- blacklisting arguments, with compile-time errors
- requiring that arguments follow a certain (regular) pattern, with
compile-time errors
- a way to get the __FUNCTION__ macro that's been requested several
times and not yet implemented