Is there any way to create something like this?

Adam D. Ruppe destructionator at gmail.com
Sun Oct 21 08:19:22 PDT 2012


On Sunday, 21 October 2012 at 13:10:16 UTC, RenatoUtsch wrote:
> Is there any way to make the GeneralLibrary class and the 
> createLibrary() (or even better, make the GeneralLibrary 
> constructor do that) to work with this kind of construction?

Yes, there's ways to do that, but they might not be what you had 
in mind, because you'll either have to use different static types 
for each version or make GeneralLibrary a dynamic type, which 
means it will error at runtime rather than compile time.

Either way, createLibrary will probably have to be a template.

Here's an example of a static wrapper:

.... I just accidentally saved over the static example with the 
dynamic example. Ugh.

I guess what I'll do is link it in:

http://arsdnet.net/dcode/example_dynamic.d

Look at the function createLibrary and pretend the 
dynamicFunctionCall method wasn't there. That's what the static 
example looked like - just opDispatch.

In main, to use the static checks, you must say auto library11 
instead of GeneralLibrary. The interface is only useful for 
dynamic calls. auto gives you the wrapper class with static 
checks.

This isn't very interesting because the wrapper adds nothing; you 
might as well just construct the original object. But you could 
change the function in the wrapper to do something else.

But anyway, each wrapper class created inherits from a 
GeneralLibrary interface, so you could pass them around.. but 
since the interface does nothing, you really have to use auto on 
the return type to actually use the class.

If you aren't doing anything with the wrapper, you could also 
just alias GeneralLibrary to be the newest version of the actual 
class too.



Not much fun so let's look at a dynamic option. This will suck 
too, but in different ways.


This one won't work with overloaded functions, default parameters 
on functions (sad, fixable in some cases, but not all), has a 
speed hit (you could help this a bit by optimizing 
dynamicFunctionCall, but it will always have some slowdown), and 
returns Variants instead of the original type, which is kinda 
annoying.

And, of course, it is a dynamic call, so any failures will only 
happen at runtime.

Here's some code:
http://arsdnet.net/dcode/example_dynamic.d


I haven't tested it fully, but it seems to throw exceptions at 
the right times for the simple functions in here.

This code is messier and includes a compiler bug hack (I 
think)... but it worked. There's some comments in there to talk 
about what it does.

End result:

given
     GeneralLibrary library11 = createLibrary!("1.1");

     library11.func1(); // Should work
     library11.func11(); // Should work
     library11.func12(); // Should fail // line 103

Will throw at runtime:
test4.NoSuchMethodException at test4.d(103): No such method: func12


And it *should* work with types too, still doing strong type 
checks, but doing them at runtime for the arguments. All return 
values for these functions are wrapped in Variants, so you'll 
have to pull them out dynamically too..

You could probably combine these two examples and have static 
types if you use auto and dynamic if you use the GeneralLibrary 
interface.




Another option might be to have the createLibrary function be 
aware of all the versions - you'd have to hard code a list that 
it can read at compile time - and then do the kind of thing in 
the static example, but trying to cast to the newer versions of 
the class and throwing if it fails. Then you'd keep the static 
types, but get dynamic checks on if the method is available.

This would be just a loop, cast to a newer class, if not null and 
the call compiles, call the function.

I'm out of screwing around time this morning so I won't write 
this one up, but  it should be doable.


More information about the Digitalmars-d mailing list