switch case alternative

TheFlyingFiddle theflyingfiddle at gmail.com
Sat Nov 2 13:19:51 PDT 2013


On Saturday, 2 November 2013 at 18:19:43 UTC, seany wrote:
> Hello,
>
> I have the following problem.
>
> In the input consol I can input a string, and the system will 
> take action based on such.
>
> So if I input add_2_with_2, it will give me a 4, if I input 
> sqrt_4 it will give me 2, etc. Generally, you will do this with 
> a switch / case command, but the problem is, then I need a 
> condition for each case. So if i want to ADITTIONALLY input 
> cube_2, then I have to write a case for this.
>
> However, I would like to do the same without having to 
> explicitly write a case each time I insert a new command. So 
> forexample, if in input "FUNCTION_1", then the program should 
> look in a specific place, in a specific forlder / file, find 
> out if the function is defined, and execute it. If not defined 
> in the file / folder, then it should throw AN EXCEPTION. If I 
> additionally want to input "FUNCTION_2", then i will define the 
> function in the same file or folder (whatever is possible with 
> D) and then let the original program to automatically search 
> and execute.
>
> Can this be done in D?
>
> (sorry for stupid question and bad English)

It's not a bad qustion! However plz use the Dlang.lern subform 
for posts like this.

To do what you want to do compile time reflection comes to mind. 
The code
below implements the essentials you need to get such a system 
working.

In a file (lets call it functions.d) declare all the functions 
that you want your framework to be able to call. Then at compile 
time place all functions of a specific type in an assosiative 
array (dictionary), the code below does this whenever 
buildFuncDictionary is called.

//In functions.d
module functions;
import std.math;

//Some Unary functions
real square(real a) { return a * a; }
real sqrt(real a) { return std.math.sqrt(a); }
real cube(real a) { return a * a * a; }

//Some binary functions
real add(real a, real b) { return a + b; }
real sub(real a, real b) { return a - b; }
real mult(real a, real b) { return a * b; }
real div(real a, real b) { return a / b; }

module math;
import functions;

alias real function(real) UnaryNumberFunc;
enum unaryNumberFunctions = buildFuncDict!(UnaryNumberFunc, 
functions);

alias real function(real, real) BinaryNumberFunc;
enum binaryNumberFunctions = buildFuncDict!(BinaryNumberFunc, 
functions);

//Builds an AA at compile time over all avalible functions from
//The specified module of the Type specified.
FuncType[string] buildFuncDict(FuncType, alias module_)()
{
     import std.typetuple;
     FuncType[string] functions;
     foreach(member; __traits(allMembers, module_)) {
	//Member is just a string. This gets the actual function.
	//We use a typetuple since this is the only way to store the
	//alias member. (I think)
	alias TypeTuple!(__traits(getMember, module_, member)) 
actualMember;
		
	static if(is(typeof(&actualMember[0]) == FuncType)) {
	    //Gets the name of the function;
	    string name = __traits(identifier, actualMember[0]);
	    //Takes the function and places it in the dictionary.
             functions[name] = &actualMember[0];
         }
     }

     return functions;
}

void main()
{
    import std.stdio;
	
    writeln(unaryNumberFunctions["square"](10));    //Prints 100
    writeln(binaryNumberFunctions["add"](10, 10)); //Prints 20     
             writeln(binaryNumberFunctions["sub"](10,5));	  
//Prints 5;

     readln();
}




More information about the Digitalmars-d mailing list