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