is it possible to have a default property for any given class ?

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Jun 7 15:55:36 UTC 2021


On Mon, Jun 07, 2021 at 03:26:27PM +0000, someone via Digitalmars-d-learn wrote:
> Consider the following code:
> 
> ```d
> class classComputer {
[...]
> }
> 
> class classComputers {
> 
>    classComputers lhs;
>    classComputers rhs;
> 
>    int opApply(int delegate(classComputers) dg) { /// boilerplate code to
> handle the class's default collection
> 
>       if (lhs && lhs.opApply(dg)) return 1;
>       if (dg(this)) return 1;
>       if (rhs && rhs.opApply(dg)) return 1;
>       return 0;
> 
>    }
> 
>    public classComputer[] computers; /// how can I tag this as the default
> property ?

	alias computers this;

> 
> }
> 
> void main (
> 
>    ) {
> 
>    classComputers lobjComputers = new classComputers;
>    lobjComputers.computers ~= new classComputer("dell");
>    lobjComputers.computers ~= new classComputer("ibm");
>    lobjComputers.computers ~= new classComputer("apple");
>    lobjComputers.computers[1].name = r"lenovo";
> 
>    foreach(lobjComputer; lobjComputers.computers) {
> writeln(lobjComputer.name); }
> 
>    ///foreach(lobjComputer; lobjComputers) { writeln(lobjComputer.name); }
> /// with default property (if possible)
> 
> }
> ```
> 
> The above code works correctly, however, avoiding the redundancy of
> lobjComputers.computers will be a plus.
> 
> Also tell me if the collection is implemented the right way, it is my
> first code using the opApply() delegate which I don't deeply
> understand for the time being.

It's very simple. Whenever some non-array object appears on the right
side of a foreach() statement, the compiler looks for a method on the
object called .opApply. If it exists, the loop body is passed to that
method as a delegate.  IOW:

	// This:
	foreach (item; myCollection) {
		/* loop body here */
	}

	// Gets translated to this:
	myCollection.opApply((item) { /* loop body here */ });


Given that, your .opApply method doesn't really do what you want. It
should instead be written like this:

	// N.B.: dg is NOT the type of the collection, but the
	// individual item you want to iterate over.
	int opApply(int delegate(classComputer) dg)
	{
		// Loop over the computers in the current node first
		foreach (computer; computers) {
			// Pass single item to loop body.
			auto ret = dg(computer);

			// N.B.: do NOT assume a non-zero return value
			// will always be 1; it may not be if your loop
			// body contains `break` or `continue`.
			if (ret) return ret;
		}

		// Now recurse child nodes
		if (lhs) {
			auto ret = lhs.opApply(dg);
			if (ret) return ret; // again, don't assume it will be 1
		}
		if (rhs) {
			auto ret = rhs.opApply(dg);
			if (ret) return ret; // again, don't assume it will be 1
		}
		return 0;
	}


T

-- 
Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubert


More information about the Digitalmars-d-learn mailing list