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

someone someone at somewhere.com
Mon Jun 7 19:28:59 UTC 2021


On Monday, 7 June 2021 at 15:55:36 UTC, H. S. Teoh wrote:

Thanks for your reply. It was very illustrating.

> 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:
>
>```d
> 	// 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.
>
>```d
> 	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;
> 	}
>```

For the sake of clarity (to me) and, given I never liked code 
with multiple returns, I rewrote your code (providing I am not 
introducing flaws) as following:

```d
class classComputers {

    classComputers lhs;
    classComputers rhs;

    int opApply(int delegate(classComputer) dg) { /// boilerplate 
code to handle the class's default collection

       int lintResult = 0;

		foreach (lobjComputer; computers) { /// looping over the 
computers starting in current node

			lintResult = dg(lobjComputer); /// passing single object to 
the loop body

			if (lintResult != 0) { break; }

		}

       if (lintResult != 0 && lhs) { lintResult = lhs.opApply(dg); 
} /// recursing child nodes
       if (lintResult != 0 && rhs) { lintResult = rhs.opApply(dg); 
} /// recursing child nodes

       return lintResult;

    }

    public classComputer[] computers; alias computers this; /// 
ie: default property

}
```

It seems it works perfectly well.

Also, your:

```d
alias computers this;
```

was very clever, indeed :)


More information about the Digitalmars-d-learn mailing list