www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Properties for arrays.

reply nail <nail_member pathlink.com> writes:
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
Mar 01 2005
next sibling parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
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 
Mar 01 2005
next sibling parent "Carlos Santander B." <csantander619 gmail.com> writes:
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
Mar 01 2005
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
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 
Mar 01 2005
parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
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
Mar 01 2005
prev sibling parent nail <nail_member pathlink.com> writes:
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
Mar 02 2005
prev sibling next sibling parent Norbert Nemec <Norbert Nemec-online.de> writes:
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
Mar 01 2005
prev sibling parent Derek Parnell <derek psych.ward> writes:
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
Mar 01 2005