January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Friday, 17 January 2014 at 17:50:54 UTC, H. S. Teoh wrote:
> On Fri, Jan 17, 2014 at 05:29:14PM +0000, Gary Willoughby wrote:
>> On Friday, 17 January 2014 at 15:56:46 UTC, H. S. Teoh wrote:
>> >Couldn't you just return a Variant? I thought this is what Variants
>> >are made for.
>> >
>> >
>> >T
>>
>> Yes but then i would need to coerce it to get it's underlying type.
>
> But isn't that what you'd have to do anyway? I mean, how else would the
> following code work?
>
> class DynClass {
> ...
> auto opDispatch(string field)() {
> return dotDotDotMagic();
> }
> }
>
> void main(string[] args) {
> auto d = new DynClass();
> if (args[1] == "int")
> d.abc = 123; // d.abc = int
> else
> d.abc = "xyz"; // d.abc = string
>
> // Suppose this somehow works:
> auto x = d.abc; // what's the type of x?
> }
>
> Since the type of x must be known at compile-time, but the type of d.abc
> can't be known until runtime, the above code can't possibly work unless
> d.abc returns a Variant. It's simply not possible for a
> runtime-determined type to be put into a variable of compile-time
> determined type without some kind of runtime check.
>
> Now I'm not sure if Variant allows assignment to a static type, but in
> theory this should be possible:
>
> // assume d.abc returns a Variant
> int x = d.abc; // will assert if d.abc doesn't hold an int at runtime
>
>
> T
In the example in my original post the types are known at compile time but they are different between properties. I wondered if there was a solution to storing and retrieving while preserving the original type via opDispatch.
I have a working solution but it only stores the base type. So i f i have an inheritance chain like this:
A -> B -> C
I can store properties of type A, B and C but when i retrieve them they all come back as A because of array covariance. I wonder if there is a way of casting them automagically to the correct type.
|
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | > I can store properties of type A, B and C but when i retrieve them they all come back as A because of array covariance. I wonder if there is a way of casting them automagically to the correct type.
So you basically want to declare a classmember for every name opDispatch is called with? That is not possible;
I thought about declaring it static in opDispatch itself, but than you can only have one instance. Next thought: Declare a static hashmap and store the values there, but then you could just use std.variant.
|
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Fri, Jan 17, 2014 at 06:49:25PM +0000, Gary Willoughby wrote: [...] > In the example in my original post the types are known at compile time but they are different between properties. I wondered if there was a solution to storing and retrieving while preserving the original type via opDispatch. > > I have a working solution but it only stores the base type. So i f i have an inheritance chain like this: > > A -> B -> C > > I can store properties of type A, B and C but when i retrieve them they all come back as A because of array covariance. I wonder if there is a way of casting them automagically to the correct type. Is it possible, at compile-time, to determine the type just from the property name alone? If not (i.e., different class instances may have a property named "abc" map to int or string, respectively), then this is not possible, because the return type of opDispatch can only depend on its compile-time parameter, that is, the property name. If there's a compile-time procedure for determining the type of a property solely from its name, then yes, this is possible. What you do is to first determine the return type from the property name (at compile-time!), hash the .mangleof of this type, and store an AA of AA's of property values, with the outer AA keyed by the hash value. Something like this: class MyClass { Variant[string][size_t] props; auto opDispatch(string ident)() { alias returnType = ... /* determine type from ident */; enum id = hashOf(T.mangleof); // unique ID for T return cast(returnType)props[id][ident]; } } The success of this depends on whether it's possible to determine the return type from the property name (at compile-time), though. If that's not possible, then this doesn't work. T -- Acid falls with the rain; with love comes the pain. |
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Fri, Jan 17, 2014 at 07:08:54PM +0000, Tobias Pankrath wrote: > >I can store properties of type A, B and C but when i retrieve them they all come back as A because of array covariance. I wonder if there is a way of casting them automagically to the correct type. > > So you basically want to declare a classmember for every name opDispatch is called with? That is not possible; > > I thought about declaring it static in opDispatch itself, but than you can only have one instance. Next thought: Declare a static hashmap and store the values there, but then you could just use std.variant. One of the reasons this breaks down is because of situations like this: class MyClass { ... auto opDispatch(string op)() { return ... /* assume we magically return the right type here */; } } // Which of these assignments to 'abc' should determine its // type? What if the function that gets called is determined at // runtime only? What if they are in two separately-compiled // modules? void fun(MyClass o) { o.abc = 123; } void gun(MyClass o) { o.abc = "xyz"; } auto x = o.abc; // what's the type of x? Another problematic case: auto o = new MyClass; auto p = new MyClass; o.abc = 123; p.abc = "xyz"; // Problem: now the return type of opDispatch cannot be // determined at compile-time. Now, if you decide beforehand that "abc" is always an int, and "def" is always a string, then this problem is avoided: o.abc = 123; // OK p.abc = 123; // OK o.abc = "xyz"; // compile error p.abc = "xyz"; // compile error o.def = "xyz"; // OK p.def = "xyz"; // OK o.def = 123; // compile error p.def = 123; // compile error T -- Freedom of speech: the whole world has no right *not* to hear my spouting off! |
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2014-01-17 18:49, H. S. Teoh wrote: > Now I'm not sure if Variant allows assignment to a static type, but in > theory this should be possible: > > // assume d.abc returns a Variant > int x = d.abc; // will assert if d.abc doesn't hold an int at runtime It doesn't work. Variant doesn't retain the static type, which is needed in this case. -- /Jacob Carlborg |
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Fri, Jan 17, 2014 at 09:08:50PM +0100, Jacob Carlborg wrote: > On 2014-01-17 18:49, H. S. Teoh wrote: > > >Now I'm not sure if Variant allows assignment to a static type, but in theory this should be possible: > > > > // assume d.abc returns a Variant > > int x = d.abc; // will assert if d.abc doesn't hold an int at runtime > > It doesn't work. Variant doesn't retain the static type, which is needed in this case. [...] Is that because D doesn't have implicit casting via opCast? -- because, conceivably, if x = d.abc; gets lowered to x = d.opCast!(typeof(x))(d.abc); then the above can be made to work. T -- If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. Chesterton |
January 17, 2014 Re: Is it possible to store properties via opDispatch using tuples? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2014-01-17 22:14, H. S. Teoh wrote: > Is that because D doesn't have implicit casting via opCast? -- because, > conceivably, if > > x = d.abc; > > gets lowered to > > x = d.opCast!(typeof(x))(d.abc); > > then the above can be made to work. I don't know, maybe. -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation