Get class from string - call function by string name

Well, what I'm trying to do is harder, but I'll try to explain.

Let's say we want (at compile time) an entire derivedMembersclass someClass. Then we just did:

const string[] methods = [__traits(derivedMembers,someClass)];

Now, how can we get someClassout "someClass"? (yep, its string representation).


Let me explain a little more what I'm trying to do:

I want to create an "intermediate" function that takes a name functionas an argument (along with an array of params) and calls the corresponding function from the list of available static methods in a specific (predefined) set of classes, Like execute("someFunc",["one","two","three"]);.

Here's the full (test) code:

class Math {
    static string noArgs(string[] s) { writeln(s); return ""; }
    static string withOneArg(string[] s) { writeln(s); return ""; }
    static string withTwoArgs(string[] s) { writeln(s); return ""; }
}

string cases()
{
    string ret = "";

    const string[] methods = [__traits(derivedMembers,Math)];

    foreach (string s; methods)
    {
        ret ~= "case \"" ~ s ~ "\": return Math."~s~"(params);";
    }

    return ret;
}

string execute(string what, string[] params)
{
    switch (what)
    {
        mixin(cases());
        default: break;
    }
    return "";
}

, Math. , D- , , [Math,String,SomethingElse] - ( )?


UPDATE:

- :

const string[] methods = [__traits(derivedMembers,mixin("Math")];

, Cannot interpret Math at compile time.


2:

, Object.factory("Math"), . (, Math?)

+4
1

, :

import std.stdio;

class Math {
    static string noArgs(string[] s) { writeln(s); return ""; }
    static string withOneArg(string[] s) { writeln(s); return ""; }
    static string withTwoArgs(string[] s) { writeln(s); return ""; }
}

class String {
    static string oneArg(string[] s) { return null; }
}

string execute(string what, string[] params) {
    import std.string;
    auto parts = what.split(".");
    auto className = parts[0];
    auto methodName = parts[1];

    import std.typetuple;
    switch(className) {
        default: assert(0, "unknown class");
        foreach(possibleClass; TypeTuple!(Math, String)) {
            case possibleClass.stringof:
                switch(methodName) {
                    default: assert(0, "unknown method");
                    foreach(memberName; __traits(derivedMembers, possibleClass)) {
                        case memberName:
                            return __traits(getMember, possibleClass, memberName)(params);
                        break;
                    }
                }
            break;
        }
    }
    assert(0);
}

void main() {
    execute("Math.withOneArg", ["cool"]);
    execute("String.oneArg", ["cool"]);
}

, mixin, . , , TypeTuple , . mixin, , ; possibleClasses execute , , undefined , .

mixin, , , . , D: foreach (.. foreach , TypeTuple, , __traits...), case!

, , , switch , , foreach , , , case that_loop_var: , .

, __traits(getMember) mixin . , IMO - . , ( __traits(getOverloads) __traits(getMember), ).

, switch es case. switch , break label_name_here;, , . continue .

, -, string[] , std.traits. , , - , std.traits.ParameterTypeTuple ReturnType , , .

+5

Source: https://habr.com/ru/post/1536541/


All Articles