diff --git a/doc/tutorial-conditions.md b/doc/tutorial-conditions.md index 6782a05fbf9c..52894c03e3ce 100644 --- a/doc/tutorial-conditions.md +++ b/doc/tutorial-conditions.md @@ -43,12 +43,13 @@ $ ./example numbers.txt An example program that does this task reads like this: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -71,10 +72,9 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - // Path takes a generic by-value, rather than by reference - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); // 1. Iterate over the lines of our file. @@ -242,13 +242,14 @@ If the example is rewritten to use failure, these error cases can be trapped. In this rewriting, failures are trapped by placing the I/O logic in a sub-task, and trapping its exit status using `task::try`: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; use std::task; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -280,8 +281,8 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { @@ -346,12 +347,13 @@ If no handler is found, `Condition::raise` will fail the task with an appropriat Rewriting the example to use a condition in place of ignoring malformed lines makes it slightly longer, but similarly clear as the version that used `fail!` in the logic where the error occurs: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -378,8 +380,8 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { @@ -415,12 +417,13 @@ To trap a condition, use `Condition::trap` in some caller of the site that calls For example, this version of the program traps the `malformed_line` condition and replaces bad input lines with the pair `(-1,-1)`: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -452,8 +455,8 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { @@ -490,12 +493,13 @@ In the example program, the first form of the `malformed_line` API implicitly as This assumption may not be correct; some callers may wish to skip malformed lines, for example. Changing the condition's return type from `(int,int)` to `Option<(int,int)>` will suffice to support this type of recovery: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -528,8 +532,8 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { @@ -575,12 +579,13 @@ until all relevant combinations encountered in practice are encoded. In the example, suppose a third possible recovery form arose: reusing the previous value read. This can be encoded in the handler API by introducing a helper type: `enum MalformedLineFix`. -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -622,8 +627,8 @@ fn main() { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { @@ -699,12 +704,13 @@ task failed at 'called `Option::unwrap()` on a `None` value', .../libs To make the program robust — or at least flexible — in the face of this potential failure, a second condition and a helper function will suffice: -~~~~{.xfail-test} +~~~~ # #[allow(unused_imports)]; +# extern mod extra; use std::io::buffered::BufferedReader; -use std::io::fs::File; +use std::io::File; # mod BufferedReader { -# use std::io::fs::File; +# use std::io::File; # use std::io::mem::MemReader; # use std::io::buffered::BufferedReader; # static s : &'static [u8] = bytes!("1 2\n\ @@ -760,8 +766,8 @@ fn parse_int(x: &str) -> int { fn read_int_pairs() -> ~[(int,int)] { let mut pairs = ~[]; - let args = std::os::args(); - let path = Path::new(args.get_opt(1).expect("No input file parameter!").as_slice()); +# let _g = std::io::ignore_io_error(); + let path = Path::new(&"foo.txt"); let mut reader = BufferedReader::new(File::open(&path)); for line in reader.lines() { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 53b25f6fe98a..9c181aa56c22 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -186,23 +186,29 @@ while still providing feedback about errors. The basic strategy: so that nullable values do not have to be 'unwrapped' before use. These features combine in the API to allow for expressions like -`File::new("diary.txt").write_line("met a girl")` without having to -worry about whether "diary.txt" exists or whether the write -succeeds. As written, if either `new` or `write_line` encounters -an error the task will fail. +`File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))` +without having to worry about whether "diary.txt" exists or whether +the write succeeds. As written, if either `new` or `write_line` +encounters an error the task will fail. -If you wanted to handle the error though you might write +If you wanted to handle the error though you might write: - let mut error = None; - do io_error::cond(|e: IoError| { - error = Some(e); - }).in { - File::new("diary.txt").write_line("met a girl"); - } +```rust +use std::io::File; +use std::io::{IoError, io_error}; - if error.is_some() { - println("failed to write my diary"); - } +let mut error = None; +io_error::cond.trap(|e: IoError| { + error = Some(e); +}).inside(|| { + File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")); +}); + +if error.is_some() { + println("failed to write my diary"); +} +# ::std::io::fs::unlink(&Path::new("diary.txt")); +``` XXX: Need better condition handling syntax @@ -500,10 +506,16 @@ pub trait Reader { /// /// # Example /// - /// let mut reader = BufferedReader::new(File::open(&Path::new("foo.txt"))); - /// for line in reader.lines() { - /// println(line); - /// } + /// ```rust + /// use std::io; + /// # let _g = ::std::io::ignore_io_error(); + /// let mut reader = io::stdin(); + /// + /// let mut bytes = [0, .. 10]; + /// reader.read(bytes); + /// + /// if reader.eof() { println("stdin() had at most 10 bytes of data."); } + /// ``` /// /// # Failure /// @@ -1098,6 +1110,18 @@ pub trait Buffer: Reader { /// encoded unicode codepoints. If a newline is encountered, then the /// newline is contained in the returned string. /// + /// # Example + /// + /// ```rust + /// use std::io::buffered::BufferedReader; + /// use std::io; + /// # let _g = ::std::io::ignore_io_error(); + /// + /// let mut reader = BufferedReader::new(io::stdin()); + /// + /// let input = reader.read_line().unwrap_or(~"nothing"); + /// ``` + /// /// # Failure /// /// This function will raise on the `io_error` condition (except for