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