Any idea for a solution to handle overloads when dynamically implementing methods?

Gary Willoughby dev at nomad.so
Thu Sep 12 11:17:06 PDT 2013


On Wednesday, 11 September 2013 at 18:24:31 UTC, H. S. Teoh wrote:
> On Mon, Sep 09, 2013 at 10:16:42PM +0200, Gary Willoughby wrote:
>> Just wondered if i could pick you brains for a nice solution to
>> dynamically add methods to a class, paying particular 
>> attention to
>> overloads. I'm currently writing a mocking framework and
>> everything's coming along nicely and i'm wondering how to 
>> handle
>> replacing overloads of the mocked class.
>> 
>> To create a new mocked class this is the code:
>> 
>> 	auto mock = new Mock!Person();
>> 
>> Simple enough, mock now contains an extended class with all the
>> methods set to assert(false) because there are no 
>> implementations
>> yet. What i need to do is to add the implementations 
>> dynamically.
>> This is the code i propose.
>> 
>> 	mock.addMethod("getAge", int delegate(){
>> 		return 40;
>> 	});
>> 
>> 	assert(mock.getAge() == 40);
>> 
>> Which i guess would be easy to implement but it doesn't handle
>> overloads because the method string doesn't contain enough
>> information to define which overload it's implementing.
>> 
>> Any nice ideas what would be a nice way of supporting this? I
>> thought i'd ask while i have a think and get some tea. :)
>
> One idea I have is to use the built-in "typetuples" as a way of
> disambiguating between different overloads. For example, 
> something like
> this:
>
> 	// This captures the function argument type list in a form that
> 	// we can call .mangleof on.
> 	template ArgTypesWrapper(ArgTypes...) { }
>
> 	// This builds a unique string to identify a specific overload
> 	// based on the function name and the .mangleof of its argument
> 	// types. The key to this trick is that the .mangleof of a
> 	// template encodes its argument types, so it is unique per
> 	// combination of argument types.
> 	template FuncSignature(string funcName, ArgTypes...) {
> 		enum FuncSignature = funcName ~ ArgTypesWrapper.mangleof;
> 	}
>
> 	class Mock(... /* whatever you currently have here */) {
> 		// This unfortunately has to be a template function in
> 		// order to be able to capture the argument types of the
> 		// delegate in the typetuple A. This may complicate the
> 		// implementation of how you'd actually dispatch to the
> 		// overload implementation at runtime.
> 		void addMethod(R, A...)(string funcName, R delegate(A...) dg)
> 		{
> 			string overloadName = FuncSignature!(funcName, A);
>
> 			// Now overloadName should be a unique string
> 			// representing that particular combination of
> 			// function name and argument types, i.e., it's
> 			// a function signature. So you can use it to
> 			// identify which overload is which.
> 		}
> 	}
>
>
> T

Thanks for the idea, i have implemented something based on this 
and it seems to be working well.


More information about the Digitalmars-d-learn mailing list