Jump to page: 1 2
Thread overview
Is it possible to store properties via opDispatch using tuples?
Jan 16, 2014
Gary Willoughby
Jan 16, 2014
bearophile
Jan 16, 2014
Gary Willoughby
Jan 16, 2014
bearophile
Jan 16, 2014
Gary Willoughby
Jan 17, 2014
Jacob Carlborg
Jan 17, 2014
Jacob Carlborg
Jan 17, 2014
H. S. Teoh
Jan 17, 2014
Gary Willoughby
Jan 17, 2014
H. S. Teoh
Jan 17, 2014
Gary Willoughby
Jan 17, 2014
Tobias Pankrath
Jan 17, 2014
H. S. Teoh
Jan 17, 2014
H. S. Teoh
Jan 17, 2014
Jacob Carlborg
Jan 17, 2014
H. S. Teoh
Jan 17, 2014
Jacob Carlborg
January 16, 2014
What i would like to achieve is to dynamically assign and retrieve properties without declaring them first. For example:

class T
{
    public this()
    {
        this.foo = "bar";
    }
}

Ordinarily the above won't compile because 'foo' hasn't been declared but with opDispatch i can handle this. The problem is how do i handle different types of each property.

I was thinking about something like this:

class A
{
}

class B : A
{
}

class C : B
{
}

class T
{
    private Tuple[string] _properties;

    public this()
    {
        this.a = new A();
        this.b = new B();
        this.c = new C();
    }

    public void opDispatch(string name, T)(T element)
    {
        this._properties[name] = Tuple(T, element);
    }

    public auto opDispatch(string name)()
    {
        if (name in this._properties)
        {
            return cast(this._properties[name][0])this._properties[name][1];
        }
    }
}

Of course this doesn't compile but is this actually possible? i.e. storing the type and data. Then on retrieval returning the correct data cast to the correct type? All done dynamically without any property being pre-declared.
January 16, 2014
Gary Willoughby:

> What i would like to achieve is to dynamically assign and retrieve properties without declaring them first.

Do you mean something like this?
http://rosettacode.org/wiki/Add_a_variable_to_a_class_instance_at_runtime#D

Bye,
bearophile
January 16, 2014
On Thursday, 16 January 2014 at 21:48:14 UTC, bearophile wrote:
> Gary Willoughby:
>
>> What i would like to achieve is to dynamically assign and retrieve properties without declaring them first.
>
> Do you mean something like this?
> http://rosettacode.org/wiki/Add_a_variable_to_a_class_instance_at_runtime#D
>
> Bye,
> bearophile

Yes exactly but i would like to preserve the types of differently typed properties so i can cast them back on retrieval.
January 16, 2014
Gary Willoughby:

> Yes exactly but i would like to preserve the types of differently typed properties so i can cast them back on retrieval.

A Variant needs to keep the type of the value you have stored in, look at the Variant documentation. (But the usual limitations of a ahead-of-time compiled statically typed language apply.)

Bye,
bearophile
January 16, 2014
On Thursday, 16 January 2014 at 22:31:01 UTC, bearophile wrote:
> Gary Willoughby:
>
>> Yes exactly but i would like to preserve the types of differently typed properties so i can cast them back on retrieval.
>
> A Variant needs to keep the type of the value you have stored in, look at the Variant documentation. (But the usual limitations of a ahead-of-time compiled statically typed language apply.)
>
> Bye,
> bearophile

I didn't think about variants but would that also need coercing into the correct type?
January 17, 2014
On 2014-01-16 23:31, bearophile wrote:

> A Variant needs to keep the type of the value you have stored in, look
> at the Variant documentation. (But the usual limitations of a
> ahead-of-time compiled statically typed language apply.)

A Varian won't work, since it only stores a TypeInfo, not the static type. But perhaps that's what you're saying.

-- 
/Jacob Carlborg
January 17, 2014
On 2014-01-16 21:26, Gary Willoughby wrote:
> What i would like to achieve is to dynamically assign and retrieve
> properties without declaring them first. For example:
>
> class T
> {
>      public this()
>      {
>          this.foo = "bar";
>      }
> }
>
> Ordinarily the above won't compile because 'foo' hasn't been declared
> but with opDispatch i can handle this. The problem is how do i handle
> different types of each property.
>
> I was thinking about something like this:
>
> class A
> {
> }
>
> class B : A
> {
> }
>
> class C : B
> {
> }
>
> class T
> {
>      private Tuple[string] _properties;
>
>      public this()
>      {
>          this.a = new A();
>          this.b = new B();
>          this.c = new C();
>      }
>
>      public void opDispatch(string name, T)(T element)
>      {
>          this._properties[name] = Tuple(T, element);
>      }
>
>      public auto opDispatch(string name)()
>      {
>          if (name in this._properties)
>          {
>              return
> cast(this._properties[name][0])this._properties[name][1];
>          }
>      }
> }
>
> Of course this doesn't compile but is this actually possible? i.e.
> storing the type and data. Then on retrieval returning the correct data
> cast to the correct type? All done dynamically without any property
> being pre-declared.

I have no way of seeing this work. The problem is you need to somehow store the static type revived in opDispatch. But to store an unknown type as an instance variable you need to use a template class.

-- 
/Jacob Carlborg
January 17, 2014
On Fri, Jan 17, 2014 at 08:56:18AM +0100, Jacob Carlborg wrote:
> On 2014-01-16 21:26, Gary Willoughby wrote:
> >What i would like to achieve is to dynamically assign and retrieve properties without declaring them first. For example:
> >
> >class T
> >{
> >     public this()
> >     {
> >         this.foo = "bar";
> >     }
> >}
> >
> >Ordinarily the above won't compile because 'foo' hasn't been declared but with opDispatch i can handle this. The problem is how do i handle different types of each property.
> >
> >I was thinking about something like this:
> >
> >class A
> >{
> >}
> >
> >class B : A
> >{
> >}
> >
> >class C : B
> >{
> >}
> >
> >class T
> >{
> >     private Tuple[string] _properties;
> >
> >     public this()
> >     {
> >         this.a = new A();
> >         this.b = new B();
> >         this.c = new C();
> >     }
> >
> >     public void opDispatch(string name, T)(T element)
> >     {
> >         this._properties[name] = Tuple(T, element);
> >     }
> >
> >     public auto opDispatch(string name)()
> >     {
> >         if (name in this._properties)
> >         {
> >             return
> >cast(this._properties[name][0])this._properties[name][1];
> >         }
> >     }
> >}
> >
> >Of course this doesn't compile but is this actually possible? i.e. storing the type and data. Then on retrieval returning the correct data cast to the correct type? All done dynamically without any property being pre-declared.
> 
> I have no way of seeing this work. The problem is you need to somehow store the static type revived in opDispatch. But to store an unknown type as an instance variable you need to use a template class.
[...]

Couldn't you just return a Variant? I thought this is what Variants are made for.


T

-- 
"The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous
January 17, 2014
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.

January 17, 2014
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

-- 
There are 10 kinds of people in the world: those who can count in binary, and those who can't.
« First   ‹ Prev
1 2