go-tour: add Stringer, Reader discussions and exercises; other tweaks

LGTM=campoy
R=campoy
CC=golang-codereviews
https://golang.org/cl/118170043
diff --git a/content/methods.article b/content/methods.article
index 148e2d6..59d988b 100644
--- a/content/methods.article
+++ b/content/methods.article
@@ -14,9 +14,9 @@
 
 * Methods continued
 
-In fact, you can define a method on _any_ type you define in your package, not just structs.
+You can declare a method on _any_ type that is declared in your package, not just struct types.
 
-You cannot define a method on a type from another package, or on a basic type.
+However, you cannot define a method on a type from another package (including built in types).
 
 .play methods/methods-continued.go
 
@@ -42,18 +42,16 @@
 
 A value of interface type can hold any value that implements those methods.
 
-*Note:* The code on the left fails to compile.	
-
-`Vertex` doesn't satisfy `Abser` because	
-the `Abs` method is defined only on `*Vertex`, not `Vertex`.
+*Note:* There is an error in the example code on line 22.
+`Vertex` (the value type) doesn't satisfy `Abser` because	
+the `Abs` method is defined only on `*Vertex` (the pointer type).
 
 .play methods/interfaces.go
 
 * Interfaces are satisfied implicitly
 
 A type implements an interface by implementing the methods.
-
-_There_is_no_explicit_declaration_of_intent._
+There is no explicit declaration of intent; no "implements" keyword. 
 
 Implicit interfaces decouple implementation packages from the packages that define the interfaces: neither depends on the other.
 
@@ -63,15 +61,51 @@
 
 .play methods/interfaces-are-satisfied-implicitly.go
 
+* Stringers
+
+One of the most ubiquitous interfaces is [[//golang.org/pkg/fmt/#Stringer][`Stringer`]] defined by the [[//golang.org/pkg/fmt/][`fmt`]] package.
+
+	type Stringer struct {
+		String() string
+	}
+
+A `Stringer` is a type that can describe itself as a string. The `fmt` package
+(and many others) look for this interface to print values.
+
+.play methods/stringer.go
+
+* Exercise: Stringers
+
+Make the `IPAddr` type implement `fmt.Stringer` to print the address as
+a dotted quad.
+
+For instance, `IPAddr{1,`2,`3,`4}` should print as `"1.2.3.4"`.
+
+.play methods/exercise-stringer.go
+
 * Errors
 
-An error is anything that can describe itself as an error string. The idea is captured by the predefined, built-in interface type, `error`, with its single method, `Error`, returning a string:
+Go programs express error state with `error` values. 
+
+The `error` type is a built-in interface simliar to `fmt.Stringer`:
 
 	type error interface {
 		Error() string
 	}
 
-The `fmt` package's various print routines automatically know to call the method when asked to print an `error`.
+(As with `fmt.Stringer`, the `fmt` package looks for the `error` interface when
+printing values.)
+
+Functions often return an `error` value, and calling code should handle errors
+by testing whether the error equals `nil`.
+
+	i, err := strconv.Atoi("42")
+	if err != nil {
+		fmt.Printf("couldn't convert number: %v\n", err)
+	}
+	fmt.Println("Converted integer:", i)
+
+A nil `error` denotes success; a non-nil `error` denotes failure.
 
 .play methods/errors.go
 
@@ -97,6 +131,47 @@
 
 .play methods/exercise-errors.go
 
+* Readers
+
+The `io` package specifies the `io.Reader` interface,
+which represents the read end of a stream of data.
+
+The Go standard library contains [[http://golang.org/search?q=Read#Global][many implementations]] of these interfaces, including files, network connections, compressors, ciphers, and others.
+
+The `io.Reader` interface has a `Read` method:
+
+	func (T) Read(b []byte) (n int, err error)
+
+`Read` populates the given byte slice with data and returns the number of bytes
+populated and an error value. It returns an `io.EOF` error when the stream
+ends.
+
+The example code creates a 
+[[//golang.org/pkg/strings/#Reader][`strings.Reader`]].
+and consumes its output 8 bytes at a time.
+
+.play methods/reader.go
+
+* Exercise: Readers
+
+Implement a `Reader` type that emits an infinite stream of the ASCII character
+`'A'`.
+
+.play methods/exercise-reader.go
+
+* Exercise: rot13Reader
+
+A common pattern is an [[http://golang.org/pkg/io/#Reader][io.Reader]] that wraps another `io.Reader`, modifying the stream in some way.
+
+For example, the [[http://golang.org/pkg/compress/gzip/#NewReader][gzip.NewReader]] function takes an `io.Reader` (a stream of compressed data) and returns a `*gzip.Reader` that also implements `io.Reader` (a stream of the decompressed data).
+
+Implement a `rot13Reader` that implements `io.Reader` and reads from an `io.Reader`, modifying the stream by applying the [[http://en.wikipedia.org/wiki/ROT13][rot13]] substitution cipher to all alphabetical characters.
+
+The `rot13Reader` type is provided for you.
+Make it an `io.Reader` by implementing its `Read` method.
+
+.play methods/exercise-rot-reader.go
+
 * Web servers
 
 [[http://golang.org/pkg/net/http/][Package http]] serves HTTP requests using any value that implements `http.Handler`:
@@ -134,6 +209,10 @@
 	http.Handle("/string", String("I'm a frayed knot."))
 	http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})
 
+#appengine: *Note:* This example won't run through the web-based tour user
+#appengine: interface. To try writing web servers you may want to
+#appengine: [[http://golang.org/doc/install/][Install Go]].
+
 .play methods/exercise-http-handlers.go
 
 * Images
@@ -148,9 +227,13 @@
 		At(x, y int) color.Color
 	}
 
+*Note*: the `Rectangle` return value of the `Bounds` method is actually an
+[[http://golang.org/pkg/image/#Rectangle][`image.Rectangle`]], as the
+declaration is inside package `image`.
+
 (See [[http://golang.org/pkg/image/#Image][the documentation]] for all the details.)
 
-Also, `color.Color` and `color.Model` are interfaces, but we'll ignore that by using the predefined implementations `color.RGBA` and `color.RGBAModel`. These interfaces and types are specified by the [[http://golang.org/pkg/image/color/][image/color package]]
+The `color.Color` and `color.Model` types are also interfaces, but we'll ignore that by using the predefined implementations `color.RGBA` and `color.RGBAModel`. These interfaces and types are specified by the [[http://golang.org/pkg/image/color/][image/color package]]
 
 .play methods/images.go
 
@@ -168,18 +251,6 @@
 
 .play methods/exercise-images.go
 
-* Exercise: Rot13 Reader
-
-A common pattern is an [[http://golang.org/pkg/io/#Reader][io.Reader]] that wraps another `io.Reader`, modifying the stream in some way.
-
-For example, the [[http://golang.org/pkg/compress/gzip/#NewReader][gzip.NewReader]] function takes an `io.Reader` (a stream of gzipped data) and returns a `*gzip.Reader` that also implements `io.Reader` (a stream of the decompressed data).
-
-Implement a `rot13Reader` that implements `io.Reader` and reads from an `io.Reader`, modifying the stream by applying the [[http://en.wikipedia.org/wiki/ROT13][ROT13]] substitution cipher to all alphabetical characters.
-
-The `rot13Reader` type is provided for you.  Make it an `io.Reader` by implementing its `Read` method.
-
-.play methods/exercise-rot-reader.go
-
 * Congratulations!
 
 You finished this lesson!
diff --git a/content/methods/exercise-reader.go b/content/methods/exercise-reader.go
new file mode 100644
index 0000000..7428ae9
--- /dev/null
+++ b/content/methods/exercise-reader.go
@@ -0,0 +1,11 @@
+package main
+
+import "code.google.com/p/go-tour/reader"
+
+type MyReader struct{}
+
+// TODO: Add a Read(byte) (int, error) method to MyReader.
+
+func main() {
+	reader.Validate(MyReader{})
+}
diff --git a/content/methods/exercise-rot-reader.go b/content/methods/exercise-rot-reader.go
index edf63ba..ff22119 100644
--- a/content/methods/exercise-rot-reader.go
+++ b/content/methods/exercise-rot-reader.go
@@ -13,8 +13,7 @@
 }
 
 func main() {
-	s := strings.NewReader(
-		"Lbh penpxrq gur pbqr!")
+	s := strings.NewReader("Lbh penpxrq gur pbqr!")
 	r := rot13Reader{s}
 	io.Copy(os.Stdout, &r)
 }
diff --git a/content/methods/exercise-stringer.go b/content/methods/exercise-stringer.go
new file mode 100644
index 0000000..ef656b4
--- /dev/null
+++ b/content/methods/exercise-stringer.go
@@ -0,0 +1,17 @@
+package main
+
+import "fmt"
+
+type IPAddr [4]byte
+
+// TODO: Add a "String() string" method to IPAddr.
+
+func main() {
+	addrs := map[string]IPAddr{
+		"loopback":  {127, 0, 0, 1},
+		"googleDNS": {8, 8, 8, 8},
+	}
+	for n, a := range addrs {
+		fmt.Printf("%v: %v\n", n, a)
+	}
+}
diff --git a/content/methods/reader.go b/content/methods/reader.go
new file mode 100644
index 0000000..f22a1f2
--- /dev/null
+++ b/content/methods/reader.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"strings"
+)
+
+func main() {
+	r := strings.NewReader("Hello, Reader!")
+
+	b := make([]byte, 8)
+	for {
+		n, err := r.Read(b)
+		fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
+		fmt.Printf("b[:n] = %q\n", b[:n])
+		if err == io.EOF {
+			break
+		}
+	}
+}
diff --git a/content/methods/stringer.go b/content/methods/stringer.go
new file mode 100644
index 0000000..9fb98b5
--- /dev/null
+++ b/content/methods/stringer.go
@@ -0,0 +1,18 @@
+package main
+
+import "fmt"
+
+type Person struct {
+	Name string
+	Age  int
+}
+
+func (p Person) String() string {
+	return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
+}
+
+func main() {
+	a := Person{"Arthur Dent", 42}
+	z := Person{"Zaphod Beeblebrox", 9001}
+	fmt.Println(a, z)
+}
diff --git a/reader/validate.go b/reader/validate.go
new file mode 100644
index 0000000..21e2f45
--- /dev/null
+++ b/reader/validate.go
@@ -0,0 +1,31 @@
+package reader
+
+import (
+	"fmt"
+	"io"
+	"os"
+)
+
+func Validate(r io.Reader) {
+	b := make([]byte, 1024)
+	i, o := 0, 0
+	for ; i < 1<<20 && o < 1<<20; i++ { // test 1mb
+		n, err := r.Read(b)
+		for i, v := range b[:n] {
+			if v != 'A' {
+				fmt.Fprintf(os.Stderr, "got byte %x at offset %v, want 'A'\n", v, o+i)
+				return
+			}
+		}
+		o += n
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "read error: %v\n", err)
+			return
+		}
+	}
+	if o == 0 {
+		fmt.Fprintf(os.Stderr, "read zero bytes after %d Read calls\n", i)
+		return
+	}
+	fmt.Println("OK!")
+}