digitalmars.D.learn - Continue iteration after exception
- Josh (17/17) Jan 23 2013 DMD 2.060, Windows 7 64-bit
- bearophile (5/6) Jan 23 2013 A possible solution: desugar the foreach range iteration protocol
- Josh (3/6) Jan 23 2013 Sorry, could you explain that a little? I'm not sure what desugar
- monarch_dodra (6/12) Jan 23 2013 He means you turn it into a normal loop with !empty, front and
- H. S. Teoh (38/52) Jan 23 2013 This may not be possible if DirEntries is implemented with opApply
- monarch_dodra (23/47) Jan 23 2013 As a workaround, one can manually and recursively iterate the
- Dmitry Olshansky (5/19) Jan 23 2013 It's a range.
DMD 2.060, Windows 7 64-bit Source: import std.file; import std.stdio; void main() { foreach (DirEntry d; dirEntries("C:\\", SpanMode.breadth)) writeln(d.name); } This code stops with "std.file.FileException std\file.d(2434): C:\Documents and Settings: Access is denied." when it gets to C:\Documents and Settings. On Windows 7 that doesn't actually exist, which is fine. What I'd like it to do is tell me that it doesn't exist, but continue iterating anyway. I've tried try-catch, but that just stops the iteration. Any help is appreciated. Thanks :) Josh
Jan 23 2013
Josh:Any help is appreciated. Thanks :)A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch. Bye, bearophile
Jan 23 2013
On Wednesday, 23 January 2013 at 15:00:16 UTC, bearophile wrote:A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch.Sorry, could you explain that a little? I'm not sure what desugar means :/
Jan 23 2013
On Wednesday, 23 January 2013 at 15:24:02 UTC, Josh wrote:On Wednesday, 23 January 2013 at 15:00:16 UTC, bearophile wrote:He means you turn it into a normal loop with !empty, front and popFront. That wouldn't really work anyways. Why you'd be able to catch the exception when calling popFront, and preserve your iteration state, you'd be unable to iterate past the exception point :/A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch.Sorry, could you explain that a little? I'm not sure what desugar means :/
Jan 23 2013
On Wed, Jan 23, 2013 at 04:52:25PM +0100, monarch_dodra wrote:On Wednesday, 23 January 2013 at 15:24:02 UTC, Josh wrote:This may not be possible if DirEntries is implemented with opApply instead of a range. Anyway, since I don't think everyone is aware of what opApply is or what a range is, here's a (very) brief explanation: In D, foreach loops can work with any user-defined type as long as they either (1) provide a method called "opApply", or (2) implement a range interface, that is, the methods "empty", "front", and "popFront". The method opApply looks like this: int opApply(scope int delegate(X...) dg) { ... } where X... represents the loop counter(s). For instance, if you want to support: foreach (int x, int y; obj) { ... } then opApply should look like: int opApply(scope int delegate(ref int x, ref int y) dg) { ... } The idea is that opApply will iterate over the contents of the object and call the delegate dg with each value (or set of values). Alternatively, the object can implement the range interface, which will also allow it to be used with std.algorithm and a whole bunch of other cool stuff. The minimal range interface requires the object to define the following methods: property bool empty() {...} // return true if there are no more elements property T front() {...} // return the current element void popFront() {...} // move to the next element The compiler then translates ("lowers") a loop like: foreach (x; obj) { do_something(x); } into: while (!obj.empty) { do_something(obj.front); obj.popFront(); } Hope this is helpful.On Wednesday, 23 January 2013 at 15:00:16 UTC, bearophile wrote:He means you turn it into a normal loop with !empty, front and popFront.A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch.Sorry, could you explain that a little? I'm not sure what desugar means :/That wouldn't really work anyways. Why you'd be able to catch the exception when calling popFront, and preserve your iteration state, you'd be unable to iterate past the exception point :/Yeah, I think we might need an enhancement request to add a flag to ignore access errors while traversing the filesystem. T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- Schoolboy
Jan 23 2013
On Wednesday, 23 January 2013 at 16:10:57 UTC, H. S. Teoh wrote:On Wed, Jan 23, 2013 at 04:52:25PM +0100, monarch_dodra wrote:As a workaround, one can manually and recursively iterate the files with a "shallow" span. The result would be a depth first iteration. //---- void foo(string s) { writeln(s); if (!s.isDir()) return; try { foreach(string dir; dirEntries(s, SpanMode.shallow)) { foo(dir); } } catch {} } void main() { foo(`C:\\`); } //----On Wednesday, 23 January 2013 at 15:24:02 UTC, Josh wrote:[SNIP]On Wednesday, 23 January 2013 at 15:00:16 UTC, bearophile wrote:He means you turn it into a normal loop with !empty, front and popFront.A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch.Sorry, could you explain that a little? I'm not sure what desugar means :/That wouldn't really work anyways. Why you'd be able to catch the exception when calling popFront, and preserve your iteration state, you'd be unable to iterate past the exception point :/Yeah, I think we might need an enhancement request to add a flag to ignore access errors while traversing the filesystem. T
Jan 23 2013
23-Jan-2013 20:09, H. S. Teoh пишет:On Wed, Jan 23, 2013 at 04:52:25PM +0100, monarch_dodra wrote:It's a range. TL;DR :) -- Dmitry OlshanskyOn Wednesday, 23 January 2013 at 15:24:02 UTC, Josh wrote:This may not be possible if DirEntries is implemented with opApply instead of a range.On Wednesday, 23 January 2013 at 15:00:16 UTC, bearophile wrote:He means you turn it into a normal loop with !empty, front and popFront.A possible solution: desugar the foreach range iteration protocol of dirEntries and wrap the relevant method with a try-catch.Sorry, could you explain that a little? I'm not sure what desugar means :/
Jan 23 2013