You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the IO module provides a mechanism for "undoing" a read operation when an error is encountered. This makes it easy to do speculative reading, where one would like to move the fileReader position back to its starting point after a failure to read some particular type or format from a file.
This is achieved using the mark, commit, and revert methods which provide a semi-low-level interface for controlling the fileReader position. See the following example where the tryReadC procedure will revert the channel position if a C cannot be read:
use IO;
class C {
var x:int;
var y:bool;
var z:3*real;
}
proc tryReadC(fr: fileReader): C throws {
var c: C;
fr.mark(); // mark a starting offsettry {
fr.read(c);
} catch e {
fr.revert(); // an error was encountered; revert to the startthrow e;
}
fr.commit(); // no errors were encountered; pop from the mark stackreturn c;
}
try {
var c = tryRead(openReader("input.txt"));
} catch e {
// try to read something else instead? ...
}
The marking logic is useful here because without it, failing to read a C would leave the fileReader position at some offset part-way through C's fields in the input. For example, if the first field was read successfully but the second wasn't, the offset would be left somewhere after the first integer in the input. This prevents the user from trying to read something else where the C started.
Although useful, the mark-commit-revert logic tends to be somewhat verbose and is likely to have repeated boilerplate used across a variety of situations. One could even imagine writing their own generic wrapper around read to avoid the repeated code:
To make "auto-reverting reads" simpler, there are a few potential improvements that could be made to the fileReader interface:
Allow fileReader's to be configured in an "auto-mark" mode, such that all read calls will mark and revert on errors internally. This way, the above tryReadC procedure wouldn't be needed, and the try-catch block could be replaced with:
try {
var c = openReader("input.txt", autoMark=true).read(C);
} catch e {
// try to read something else instead? ...
}
Add an optional argument to the read methods to enable marking (this would require solving a know limitation with combining var-args and optional arguments). Again, this would simplify the try-catch block in the above example to:
try {
var c = openReader("input.txt").read(C, mark=true);
} catch e {
// try to read something else instead? ...
}
Limitation with current design:
Currently, the IO module provides a mechanism for "undoing" a read operation when an error is encountered. This makes it easy to do speculative reading, where one would like to move the
fileReader
position back to its starting point after a failure to read some particular type or format from a file.This is achieved using the
mark
,commit
, andrevert
methods which provide a semi-low-level interface for controlling thefileReader
position. See the following example where thetryReadC
procedure will revert the channel position if a C cannot be read:The
mark
ing logic is useful here because without it, failing to read aC
would leave thefileReader
position at some offset part-way throughC
's fields in the input. For example, if the first field was read successfully but the second wasn't, the offset would be left somewhere after the first integer in the input. This prevents the user from trying to read something else where the C started.Although useful, the mark-commit-revert logic tends to be somewhat verbose and is likely to have repeated boilerplate used across a variety of situations. One could even imagine writing their own generic wrapper around
read
to avoid the repeated code:Proposals:
To make "auto-reverting reads" simpler, there are a few potential improvements that could be made to the
fileReader
interface:fileReader
's to be configured in an "auto-mark" mode, such that allread
calls will mark and revert on errors internally. This way, the abovetryReadC
procedure wouldn't be needed, and the try-catch block could be replaced with:read
methods to enable marking (this would require solving a know limitation with combining var-args and optional arguments). Again, this would simplify the try-catch block in the above example to:mark
ing behavior of afileReader
(see: I/O module: express channel mark/revert/commit via context manager #19611 for more).For the first two proposals, the formal names would need to be decided. Additionally, these are all non-breaking changes that could be added post 2.0.
The text was updated successfully, but these errors were encountered: