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