Skip to content

Commit

Permalink
Merge pull request #21050 from steveklabnik/gh13423
Browse files Browse the repository at this point in the history
Evaluate # fn in docs

Reviewed-by: nikomatsakis
  • Loading branch information
bors committed Jan 17, 2015
2 parents 2fe1e8a + a2d3396 commit 03f7862
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 102 deletions.
82 changes: 47 additions & 35 deletions src/doc/trpl/threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ closure is limited to capturing `Send`-able data from its environment
ensures that `spawn` can safely move the entire closure and all its
associated state into an entirely different thread for execution.

```{rust,ignore}
# use std::thread::spawn;
# fn generate_thread_number() -> int { 0 }
```rust
use std::thread::Thread;

fn generate_thread_number() -> i32 { 4 } // a very simple generation

// Generate some state locally
let child_thread_number = generate_thread_number();

spawn(move || {
Thread::spawn(move || {
// Capture it in the remote thread. The `move` keyword indicates
// that this closure should move `child_thread_number` into its
// environment, rather than capturing a reference into the
Expand All @@ -77,40 +79,44 @@ The simplest way to create a channel is to use the `channel` function to create
of a channel, and a *receiver* is the receiving endpoint. Consider the following
example of calculating two results concurrently:

```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;

let (tx, rx): (Sender<int>, Receiver<int>) = channel();
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();

spawn(move || {
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});

some_other_expensive_computation();
let result = rx.recv();
# fn some_expensive_computation() -> int { 42 }
# fn some_other_expensive_computation() {}

fn some_expensive_computation() -> u32 { 42 } // very expensive ;)
fn some_other_expensive_computation() {} // even more so
```

Let's examine this example in detail. First, the `let` statement creates a
stream for sending and receiving integers (the left-hand side of the `let`,
`(tx, rx)`, is an example of a destructuring let: the pattern separates a tuple
into its component parts).

```{rust,ignore}
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
```rust
# use std::sync::mpsc;
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();
```

The child thread will use the sender to send data to the parent thread, which will
wait to receive the data on the receiver. The next statement spawns the child
thread.

```{rust,ignore}
# use std::thread::spawn;
# fn some_expensive_computation() -> int { 42 }
# let (tx, rx) = channel();
spawn(move || {
```rust
# use std::thread::Thread;
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
# let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});
Expand All @@ -125,9 +131,10 @@ computation, then sends the result over the captured channel.
Finally, the parent continues with some other expensive computation, then waits
for the child's result to arrive on the receiver:

```{rust,ignore}
```rust
# use std::sync::mpsc;
# fn some_other_expensive_computation() {}
# let (tx, rx) = channel::<int>();
# let (tx, rx) = mpsc::channel::<u32>();
# tx.send(0);
some_other_expensive_computation();
let result = rx.recv();
Expand All @@ -140,8 +147,9 @@ single `Receiver` value. What if our example needed to compute multiple
results across a number of threads? The following program is ill-typed:

```{rust,ignore}
# fn some_expensive_computation() -> int { 42 }
let (tx, rx) = channel();
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
let (tx, rx) = mpsc::channel();
spawn(move || {
tx.send(some_expensive_computation());
Expand All @@ -156,19 +164,22 @@ spawn(move || {

Instead we can clone the `tx`, which allows for multiple senders.

```{rust,ignore}
let (tx, rx) = channel();
```rust
use std::thread::Thread;
use std::sync::mpsc;

let (tx, rx) = mpsc::channel();

for init_val in range(0u, 3) {
for init_val in 0 .. 3 {
// Create a new channel handle to distribute to the child thread
let child_tx = tx.clone();
spawn(move || {
Thread::spawn(move || {
child_tx.send(some_expensive_computation(init_val));
});
}

let result = rx.recv() + rx.recv() + rx.recv();
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap();
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```

Cloning a `Sender` produces a new handle to the same channel, allowing multiple
Expand All @@ -181,21 +192,22 @@ Note that the above cloning example is somewhat contrived since you could also
simply use three `Sender` pairs, but it serves to illustrate the point. For
reference, written with multiple streams, it might look like the example below.

```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;

// Create a vector of ports, one for each child thread
let rxs = Vec::from_fn(3, |init_val| {
let (tx, rx) = channel();
spawn(move || {
let rxs = (0 .. 3).map(|&:init_val| {
let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
tx.send(some_expensive_computation(init_val));
});
rx
});
}).collect::<Vec<_>>();

// Wait on each port, accumulating the results
let result = rxs.iter().fold(0, |accum, rx| accum + rx.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() );
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```

## Backgrounding computations: Futures
Expand Down
1 change: 0 additions & 1 deletion src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@
//! }
//! # fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] }
//! }
//! # fn main() { }
//! ```
//!
//! ## Mutating implementations of `clone`
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/finally.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@
//!
//! use std::finally::Finally;
//!
//! # fn main() {
//! (|&mut:| {
//! // ...
//! }).finally(|| {
//! // this code is always run
//! })
//! # }
//! ```

#![deprecated = "It is unclear if this module is more robust than implementing \
Expand Down
17 changes: 11 additions & 6 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ macro_rules! panic {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// assert!(true);
/// # fn some_computation() -> bool { true }
///
/// fn some_computation() -> bool { true } // a very simple function
///
/// assert!(some_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3i; let b = 27i;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
Expand Down Expand Up @@ -108,13 +111,15 @@ macro_rules! assert_eq {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// debug_assert!(true);
/// # fn some_expensive_computation() -> bool { true }
///
/// fn some_expensive_computation() -> bool { true } // a very simple function
/// debug_assert!(some_expensive_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// debug_assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3; let b = 27;
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
Expand Down
3 changes: 1 addition & 2 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,7 @@ impl<T: ?Sized> Clone for ContravariantType<T> {
/// "interior" mutability:
///
/// ```
/// pub struct Cell<T> { value: T }
/// # fn main() {}
/// struct Cell<T> { value: T }
/// ```
///
/// The type system would infer that `value` is only read here and
Expand Down
4 changes: 0 additions & 4 deletions src/libcore/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@
//! # Example
//!
//! ```ignore
//! # fn main() {
//! #![feature(globs)]
//!
//! use core::prelude::*;
//! # }
//! ```

// Reexported core operators
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,9 @@
//! makes it clear:
//!
//! ```
//! # #![feature(macro_rules)]
//! macro_rules! try {
//! ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
//! }
//! # fn main() { }
//! ```
//!
//! `try!` is imported by the prelude, and is available everywhere.
Expand Down
11 changes: 2 additions & 9 deletions src/libstd/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@
//!
//! Some examples of the `format!` extension are:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("Hello"); // => "Hello"
//! format!("Hello, {}!", "world"); // => "Hello, world!"
//! format!("The number is {}", 1i); // => "The number is 1"
//! format!("{:?}", (3i, 4i)); // => "(3i, 4i)"
//! format!("{value}", value=4i); // => "4"
//! format!("{} {}", 1i, 2u); // => "1 2"
//! # }
//! ```
//!
//! From these, you can see that the first argument is a format string. It is
Expand Down Expand Up @@ -83,12 +81,10 @@
//!
//! For example, the following `format!` expressions all use named argument:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("{argument}", argument = "test"); // => "test"
//! format!("{name} {}", 1i, name = 2i); // => "2 1"
//! format!("{a} {c} {b}", a="a", b='b', c=3i); // => "a 3 b"
//! # }
//! ```
//!
//! It is illegal to put positional parameters (those without names) after
Expand Down Expand Up @@ -288,8 +284,6 @@
//! use std::fmt;
//! use std::io;
//!
//! # #[allow(unused_must_use)]
//! # fn main() {
//! fmt::format(format_args!("this returns {}", "String"));
//!
//! let some_writer: &mut io::Writer = &mut io::stdout();
Expand All @@ -299,7 +293,6 @@
//! write!(&mut io::stdout(), "{}", args);
//! }
//! my_fmt_fn(format_args!("or a {} too", "function"));
//! # }
//! ```
//!
//! The result of the `format_args!` macro is a value of type `fmt::Arguments`.
Expand Down
27 changes: 11 additions & 16 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,16 +934,15 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// A `RefReader` is a struct implementing `Reader` which contains a reference
/// to another reader. This is often useful when composing streams.
///
/// # Example
/// # Examples
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo() {
/// use std::io;
/// use std::io::ByRefReader;
/// use std::io::util::LimitReader;
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut stream = io::stdin();
///
/// // Only allow the function to process at most one kilobyte of input
Expand All @@ -953,8 +952,6 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// }
///
/// // 'stream' is still available for use here
///
/// # }
/// ```
pub struct RefReader<'a, R:'a> {
/// The underlying reader which this is referencing
Expand Down Expand Up @@ -1269,12 +1266,11 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo () {
/// use std::io::util::TeeReader;
/// use std::io::{stdin, ByRefWriter};
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut output = Vec::new();
///
/// {
Expand All @@ -1285,7 +1281,6 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// }
///
/// println!("input processed: {:?}", output);
/// # }
/// ```
pub struct RefWriter<'a, W:'a> {
/// The underlying writer which this is referencing
Expand Down Expand Up @@ -1705,19 +1700,19 @@ pub enum FileType {
/// A structure used to describe metadata information about a file. This
/// structure is created through the `stat` method on a `Path`.
///
/// # Example
/// # Examples
///
/// ```no_run
/// # #![allow(unstable)]
///
/// use std::io::fs::PathExtensions;
///
/// ```
/// # use std::io::fs::PathExtensions;
/// # fn main() {}
/// # fn foo() {
/// let info = match Path::new("foo.txt").stat() {
/// Ok(stat) => stat,
/// Err(e) => panic!("couldn't read foo.txt: {}", e),
/// };
///
/// println!("byte size: {}", info.size);
/// # }
/// ```
#[derive(Copy, Hash)]
pub struct FileStat {
Expand Down
2 changes: 0 additions & 2 deletions src/libstd/io/net/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,7 @@ impl UnixListener {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// # #![allow(unused_must_use)]
/// use std::io::net::pipe::UnixListener;
/// use std::io::{Listener, Acceptor};
///
Expand Down
Loading

0 comments on commit 03f7862

Please sign in to comment.