Thread overview
Properties for arrays.
Mar 01, 2005
nail
Mar 01, 2005
Matthew
Mar 01, 2005
Matthew
Mar 02, 2005
nail
Mar 02, 2005
Norbert Nemec
Mar 02, 2005
Derek Parnell
March 01, 2005
Hi all,

We already have properies declaration mechanism for single values, i.e. having

class MyClass
{
int foo() {...}
void foo(int i) {...}
}

we can write:

MyClass c = new MyClass();
c.foo = 5;
int a = c.foo;

Fine, but what about arrays? Consider you want to have property that looks like array outside class, e.g

MyClass c = new MyClass();
c.baz[5] = 123; // actualy want to use property.

It is imposible to implement to get action on array element change. Of course to force this snipet compilation I can define my class as

class MyClass
{
int[] baz() {...}
}

But here I get no control whether any element was changed or not. So the
suggestion is to interpret
void baz(int index, SomeArrayElementType val) {...}
as property of described behaviour, i.e making possible to write
c.baz[5] = 123;
and this method will be called with index = 5 and val = 123.

Something against?

Victor Nakoryakov
nail-mail <at> mail <dot> ru
March 01, 2005
Can you explain again, a bit more fully?

You lost me around "c.baz[5] = 123;"


"nail" <nail_member@pathlink.com> wrote in message news:d02kjl$pev$1@digitaldaemon.com...
> Hi all,
>
> We already have properies declaration mechanism for single values, i.e. having
>
> class MyClass
> {
> int foo() {...}
> void foo(int i) {...}
> }
>
> we can write:
>
> MyClass c = new MyClass();
> c.foo = 5;
> int a = c.foo;
>
> Fine, but what about arrays? Consider you want to have property that
> looks like
> array outside class, e.g
>
> MyClass c = new MyClass();
> c.baz[5] = 123; // actualy want to use property.
>
> It is imposible to implement to get action on array element change. Of
> course to
> force this snipet compilation I can define my class as
>
> class MyClass
> {
> int[] baz() {...}
> }
>
> But here I get no control whether any element was changed or not. So
> the
> suggestion is to interpret
> void baz(int index, SomeArrayElementType val) {...}
> as property of described behaviour, i.e making possible to write
> c.baz[5] = 123;
> and this method will be called with index = 5 and val = 123.
>
> Something against?
>
> Victor Nakoryakov
> nail-mail <at> mail <dot> ru


March 01, 2005
Matthew wrote:
> Can you explain again, a bit more fully?
> 
> You lost me around "c.baz[5] = 123;"
> 

Say, in a GUI library there's a ListBox class, and its implementation is done defining an items property. So, you say: myList.items[3]="foo". It'd be easy to declare items as a char [][], but if you want to trigger an ItemChangedEvent (for example), it wouldn't be enough: you'd need items to be a property.

A solution (in that specific example) is to make items a StringList or similar, which defines opIndex and opIndexAssign, and which triggers its events. They (the events) are caught by the containing ListBox only, which would trigger the event to the user's code (the double triggering is because I think StringList would be an implementation detail, that the user shouldn't know of).

However, providing a solution that doesn't need an additional class would be indeed desirable, IMHO.

_______________________
Carlos Santander Bernal
March 01, 2005
I'll give it a try, but I may not be understanding fully.

What nail is, presumably, saying is that this will work:

class C
{
	int data;

	int property()
	{
		return this.data;
	}
	void property(int val)
	{
		this.data = val;
	}
}

int main()
{
	C test = new C();

	test.property = 1;
	printf("%d\n", test.property);

	return 0;
}

But if you change all the int's to int[], you can't tell that the array is being written to:

class C
{
	int[] data;

	this()
	{
		this.data.length = 1;
		this.data[0] = 5;
	}

	int[] property()
	{
		return this.data;
	}
	void property(int[] val)
	{
		this.data = val;
	}
}

int main()
{
	C test = new C();

	test.property[0] = 3;
	printf("%d\n", test.property[0]);

	return 0;
}

Which makes sense to me, and if I did this:

	int[] newArray;
	newArray.length = 1;
	newArray[0] = 3;
	test.property = newArray;

I would assume the "setter" would be called.  Anyway, that's what I think he meant... forgive me if I'm mistaken.

-[Unknown]


> Can you explain again, a bit more fully?
> 
> You lost me around "c.baz[5] = 123;"
> 
> 
> "nail" <nail_member@pathlink.com> wrote in message news:d02kjl$pev$1@digitaldaemon.com...
> 
>>Hi all,
>>
>>We already have properies declaration mechanism for single values, i.e. having
>>
>>class MyClass
>>{
>>int foo() {...}
>>void foo(int i) {...}
>>}
>>
>>we can write:
>>
>>MyClass c = new MyClass();
>>c.foo = 5;
>>int a = c.foo;
>>
>>Fine, but what about arrays? Consider you want to have property that looks like
>>array outside class, e.g
>>
>>MyClass c = new MyClass();
>>c.baz[5] = 123; // actualy want to use property.
>>
>>It is imposible to implement to get action on array element change. Of course to
>>force this snipet compilation I can define my class as
>>
>>class MyClass
>>{
>>int[] baz() {...}
>>}
>>
>>But here I get no control whether any element was changed or not. So the
>>suggestion is to interpret
>>void baz(int index, SomeArrayElementType val) {...}
>>as property of described behaviour, i.e making possible to write
>>c.baz[5] = 123;
>>and this method will be called with index = 5 and val = 123.
>>
>>Something against?
>>
>>Victor Nakoryakov
>>nail-mail <at> mail <dot> ru 
> 
> 
> 
March 01, 2005
Got it.

I think the proxy has to be the answer, then, otherwise we'll be bedecked with myriad special cases.


"Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:d02pfh$10bv$1@digitaldaemon.com...
> I'll give it a try, but I may not be understanding fully.
>
> What nail is, presumably, saying is that this will work:
>
> class C
> {
> int data;
>
> int property()
> {
> return this.data;
> }
> void property(int val)
> {
> this.data = val;
> }
> }
>
> int main()
> {
> C test = new C();
>
> test.property = 1;
> printf("%d\n", test.property);
>
> return 0;
> }
>
> But if you change all the int's to int[], you can't tell that the array is being written to:
>
> class C
> {
> int[] data;
>
> this()
> {
> this.data.length = 1;
> this.data[0] = 5;
> }
>
> int[] property()
> {
> return this.data;
> }
> void property(int[] val)
> {
> this.data = val;
> }
> }
>
> int main()
> {
> C test = new C();
>
> test.property[0] = 3;
> printf("%d\n", test.property[0]);
>
> return 0;
> }
>
> Which makes sense to me, and if I did this:
>
> int[] newArray;
> newArray.length = 1;
> newArray[0] = 3;
> test.property = newArray;
>
> I would assume the "setter" would be called.  Anyway, that's what I think he meant... forgive me if I'm mistaken.
>
> -[Unknown]
>
>
>> Can you explain again, a bit more fully?
>>
>> You lost me around "c.baz[5] = 123;"
>>
>>
>> "nail" <nail_member@pathlink.com> wrote in message news:d02kjl$pev$1@digitaldaemon.com...
>>
>>>Hi all,
>>>
>>>We already have properies declaration mechanism for single values, i.e. having
>>>
>>>class MyClass
>>>{
>>>int foo() {...}
>>>void foo(int i) {...}
>>>}
>>>
>>>we can write:
>>>
>>>MyClass c = new MyClass();
>>>c.foo = 5;
>>>int a = c.foo;
>>>
>>>Fine, but what about arrays? Consider you want to have property that
>>>looks like
>>>array outside class, e.g
>>>
>>>MyClass c = new MyClass();
>>>c.baz[5] = 123; // actualy want to use property.
>>>
>>>It is imposible to implement to get action on array element change.
>>>Of course to
>>>force this snipet compilation I can define my class as
>>>
>>>class MyClass
>>>{
>>>int[] baz() {...}
>>>}
>>>
>>>But here I get no control whether any element was changed or not. So
>>>the
>>>suggestion is to interpret
>>>void baz(int index, SomeArrayElementType val) {...}
>>>as property of described behaviour, i.e making possible to write
>>>c.baz[5] = 123;
>>>and this method will be called with index = 5 and val = 123.
>>>
>>>Something against?
>>>
>>>Victor Nakoryakov
>>>nail-mail <at> mail <dot> ru
>>
>> 

March 02, 2005
nail schrieb:
> Hi all,
> 
> We already have properies declaration mechanism for single values, i.e. having
> 
> class MyClass
> {
> int foo() {...}
> void foo(int i) {...}
> }
> 
> we can write:
> 
> MyClass c = new MyClass();
> c.foo = 5;
> int a = c.foo;
> 
> Fine, but what about arrays? Consider you want to have property that looks like
> array outside class, e.g
> 
> MyClass c = new MyClass();
> c.baz[5] = 123; // actualy want to use property.

How about making baz a member variable of MyClass that has a type supporting opIndexAssign?

class SomeType {
	opIndexAssign(...) {
		...
	}
}

class MyClass {
	SomeType baz;
}

MyClass c = new MyClass();
c.baz[5] = 123; // will call the above opIndexAssign
March 02, 2005
On Tue, 1 Mar 2005 20:51:01 +0000 (UTC), nail wrote:

> Hi all,
> 
> We already have properies declaration mechanism for single values, i.e. having
> 
> class MyClass
> {
> int foo() {...}
> void foo(int i) {...}
> }
> 
> we can write:
> 
> MyClass c = new MyClass();
> c.foo = 5;
> int a = c.foo;
> 
> Fine, but what about arrays? Consider you want to have property that looks like array outside class, e.g
> 
> MyClass c = new MyClass();
> c.baz[5] = 123; // actualy want to use property.
> 
> It is imposible to implement to get action on array element change. Of course to force this snipet compilation I can define my class as
> 
> class MyClass
> {
> int[] baz() {...}
> }
> 
> But here I get no control whether any element was changed or not. So the
> suggestion is to interpret
> void baz(int index, SomeArrayElementType val) {...}
> as property of described behaviour, i.e making possible to write
> c.baz[5] = 123;
> and this method will be called with index = 5 and val = 123.
> 
> Something against?
> 
> Victor Nakoryakov
> nail-mail <at> mail <dot> ru

I suppose you could fake it by using two properties. One for the array and one for the index. For example, below I implement a 1-based indexed property.

import std.stdio;
class Foo
{
    private {
        int mIdx;  // Current index
        int[] mVal;
    }

    public {
        void idx(int X)
        {
            if (X > mVal.length)
                mVal.length = X;
            mIdx = X;
        }

        void val(int X)
        {
            if (mIdx > 0)
                mVal[mIdx-1] = X;
        }

        void show()
        {
            writefln("IDX ", mIdx);
            foreach(int i, int X; mVal)
            {
                writef("%d", X);
                if (i != mVal.length-1)
                    writef(", ");
            }
            writefln("");
        }
    }
}


void main()
{
    Foo A = new Foo;

    A.show();

    A.idx = 1;
    A.val = 456;
    A.show();

    A.idx = 5;
    A.val = 123;
    A.show();

    A.idx = 3;
    A.val = 789;
    A.show();
}
-- 
Derek
Melbourne, Australia
2/03/2005 12:27:41 PM
March 02, 2005
In article <d02mnp$s2s$1@digitaldaemon.com>, Matthew says...
>
>Can you explain again, a bit more fully?
>
>You lost me around "c.baz[5] = 123;"
>
>

Ok, sorry for confusion. My english is too bad to explain all I want :). So I'll try give concrete example. Imagine some class Renderer that represents some render API, OpenGL for instance. I want to have property that will be used to setup current texture for render. The main issue is that renderers support multitexturing. Consider case when renderer can use 8 textures simultaneously (texture map, bump map, light map, something else, something else). So approx class definition will be:

class Renderer
{

// Binds one concrete texture with hw
protected void bindTextureWithHardware(uint stage, uint id)
{
// Some OpenGL instructions goes here
}

Texture texture(int stage) // (1)
{
// return current texture at stage 'stage'
}

void texture(int stage, Texture tex) // (2)
{
// store texture at stage 'stage' reference sonewhere
// make some texture preparation
bindTextureWithHardware(stage, tex.id);
}

}

Having such implementation I'd like to be able use following constructions:
myRenderer[5] = myBumpMap; // (2) must be called with stage = 5 and tex =
myBumpMap.
Texture tex = myRenderer[5]; // (1) must be called with stage = 5

Using existing property mechanism I can trigger texture change (and bind it with
hw) only if whole array assigned what is very inconvinient. If generalize idea
with array properties the following take place: having methods
void prop(SomeType1 a, SomeType2 b, SomeType3 c, SomeType4 val);
SomeType4 prop(SomeType1 a, SomeType2 b, SomeType3 c);
is equivalent to have property that used in way:
someclass.prop[a, b, c] = val;
val = someclass.prop[a, b, c];

Of course, solution with dummy class is possible way out, but it too bulky. So
if we have clumsy way to declare single property why not to use same way to
declare indexed property.
Hope I delivered my thoughts.

Victor Nakoryakov
nail-mail<at>mail<dot>ru