On Wednesday, 9 December 2020 at 14:34:18 UTC, Andre Pany wrote:
Hi,
I want to port some Python coding and try have as much similiar
coding as
possible.
I thought I can have a mir variant which stores either class A
or B
and I can call at runtime a method like this:
```
/+ dub.sdl:
name "app"
dependency "mir-core" version="1.1.51"
+/
import std.stdio: writeln;
import mir.algebraic;
class A {
void foo(int i){writeln("A.foo");}
}
class B {
void foo(int i, string s){writeln("B.foo");}
}
void main() {
Variant!(A,B) v = new A();
v.foo(3);
}
```
But it fails with:
Error: static assert: "Algebraic!(A, B): the visitor cann't be
caled with arguments (B, int)"
The error message seems strange. Is the behavior I want somehow
possible?
(At runtime I know whether I have an object of A or B and will
only call
with the correct method signature).
Kind regards
André
For .member access mir.algebraic checks at compile time that all
underlying types (except typeof(null)) can be called with
provided arguments. It is kind of API protection.
Alternatives:
With compile-time known type
```
v.get!A.foo(3); // will throw if it isn't A
v.trustedGet!A.foo(3); // will assert if it isn't A
```
Without compile-time known type
```
v.tryGetMember!"foo"(3); // will throw if it isn't A
v.optionalGetMember!"foo"(3); // will return null Nullable!void
of it isn't A
```
tryGetMember and optionalGetMember are alternative visitor
handlers in mir.algebraic.
Kind regards,
Ilya