Skip to content
This repository has been archived by the owner on Nov 11, 2019. It is now read-only.
Permalink
Browse files
update for 0.10
  • Loading branch information
steveklabnik committed Apr 2, 2014
1 parent 50d2f72 commit 9e55c5702915d6f514c2ee493b174c891219a70c
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 132 deletions.
@@ -45,6 +45,8 @@ yet very different, can teach us a lot.
Here's "Hello World" in Rust:

~~~ {.rust}
use std::io::println;

This comment has been minimized.

Copy link
@alan-andrade

alan-andrade Apr 2, 2014

Do you think mentioning the existence of the println! macro would help the readers in some way ?
Just to let them know what's the difference.

This comment has been minimized.

Copy link
@steveklabnik

steveklabnik Apr 2, 2014

Author Owner

I raised the issue on the ML: https://mail.mozilla.org/pipermail/rust-dev/2014-April/009354.html

I do use and talk about println! later.

fn main() {
println("Hello, world!");
}
@@ -53,12 +55,14 @@ Here's "Hello World" in Rust:
Here's a parallel "Hello World" in Rust:

~~~ {.rust}
use std::io::println;
fn main() {
for num in range(0, 10) {
do spawn {
spawn(proc() {
let greeting_message = "Hello?";
println(greeting_message);
}
});
}
}
~~~
@@ -1,10 +1,43 @@
Installing Rust
===============

Most Rubyists use OS X, and Rust is pretty easy to get going on it:
Binary installers
-----------------

Mac OS X
--------
The Rust project provides official binary installers. You can get both releases
and nightlies. Binary installers are the fastest and easiest way to get going
with Rust. Because Rust is written in Rust, compiling the Rust compiler actually
entails compiling it three times! This means it's quite slow. But a binary install
should be snappy!

Pick your OS and your 32 or 64 bit variant.

### Linux

* http://static.rust-lang.org/dist/rust-0.10-x86_64-unknown-linux-gnu.tar.gz
* http://static.rust-lang.org/dist/rust-0.10-i686-unknown-linux-gnu.tar.gz

You'll have to run `install.sh` from inside the unzipped package.

### Mac

* http://static.rust-lang.org/dist/rust-0.10-x86_64-apple-darwin.tar.gz
* http://static.rust-lang.org/dist/rust-0.10-i686-apple-darwin.tar.gz

This should be a `.pkg` file, which you can double click to install.

### Windows (32-bit)

* http://static.rust-lang.org/dist/rust-0.10-install.exe

Double clicking an `.exe` installer should be old hat to Windows folks!

From Source
-----------

Some people prefer to build from source. It's not hard, but it does take a while!

### Mac OS X

The easiest way to get Rust going is Homebrew, which you probably
already use. Just do this:
@@ -13,42 +46,38 @@ already use. Just do this:

If you don't use Homebrew, install it. Seriously.

(Note: If you're reading this close to release, Homebrew may not have 0.9 yet,
(Note: If you're reading this close to release, Homebrew may not have 0.10 yet,
you can use brew install --HEAD rust to get master, which will be close.)

Linux
-----
### Linux

I personally use Linux, and Rust works quite well on it. Rust does the Standard
Unix Thing.

$ curl -O http://static.rust-lang.org/dist/rust-0.9.tar.gz
$ tar -xzf rust-0.9.tar.gz
$ cd rust-0.9
$ curl -O http://static.rust-lang.org/dist/rust-0.10.tar.gz
$ tar -xzf rust-0.10.tar.gz
$ cd rust-0.10
$ ./configure
$ make
$ sudo make install

Most package managers I've checked out either have no package or a really old
package, so you'll probably want to just install from source.

Windows
-------
### Windows

See instructions on the
[wiki](https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#windows).
Overall, Rust wants to have strong Windows support, but some of it is in flux,
and it was decided that the 0.8 release would be a bit wonky. Don't be afraid to
hop into [the Rust
IRC](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) and
ask for help.

Future Proofing
---------------

The version this book is written for is 0.9. While the language itself is pretty
stable, things like the standard library and some major subsystems are being
revised. I'll be tweaking it with every new release.
Overall, Rust wants to have strong Windows support, but some of it is in flux.
Don't be afraid to hop into [the Rust
IRC](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) and ask
for help.

### Future Proofing

The version this book is written for is 0.10. While the language itself is
pretty stable, things like the standard library and some major subsystems are
being revised. I'll be tweaking it with every new release.

If you run

@@ -11,6 +11,8 @@ Rust programs end in `.rs`:
Put this in it:

~~~ {.rust}
use std::io::println;
fn main() {
println("Hello, world.");
}
@@ -20,6 +20,8 @@ function runs, the test passes, and if it errors in some way, the test
fails. Let's give it a shot: Open up `testing.rs` and put this in it:

~~~ {.rust}
use std::io::println;
#[test]
fn this_tests_code() {
println("")
@@ -46,6 +48,8 @@ You should get some output that looks like this:
Bam! Now let's make it fail:

~~~ {.rust}
use std::io::println;
#[test]
fn this_tests_code() {
fail!("Fail!");
@@ -54,21 +58,29 @@ Bam! Now let's make it fail:

Recompile, and the output should be:

$ ./testing
testing.rs:1:9: 1:25 warning: unused import, #[warn(unused_imports)] on by default
testing.rs:1 use std::io::println;
^~~~~~~~~~~~~~~~

running 1 test
rust: task failed at 'Fail!', testing.rs:3
test this_tests_code ... FAILED

failures:

---- this_tests_code stdout ----
task 'this_tests_code' failed at 'Fail!', testing.rs:5


failures:
this_tests_code

result: FAILED. 0 passed; 1 failed; 0 ignored
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

task '<main>' failed at 'Some tests failed', /some/path/to/something

rust: task failed at 'Some tests failed', /build/src/rust-0.6/src/libstd/test.rs:104
rust: domain main @0x1ca49c0 root task failed

You can see it gives us the message, the file name, and the line number.
Great.
Because we removed the `println`, it complains that we've imported, but not
used it. Nice! You can see it gives us the message, the file name, and the
line number. Great.

Super simple. That's all you need to know to get started. Next up: FizzBuzz.
@@ -59,22 +59,27 @@ you'd expect, but we have curly braces rather than our friends `do/end`.
Now that we've got that cleared up, let's compile and run our tests:

$ rustc --test fizzbuzz.rs
fizzbuzz.rs:1:12: 1:16 warning: unused variable: `num`
fizzbuzz.rs:1 fn is_three(num: int) -> bool {
^~~~
fizzbuzz.rs:1:17: 1:20 warning: unused variable: `num`, #[warn(unused_variable)] on by default
fizzbuzz.rs:1 fn is_three(num: int) -> bool {
^~~

$ ./fizzbuzz

running 1 test
rust: task failed at 'One is not three', fizzbuzz.rs:8
test test_is_three ... FAILED

failures:

---- test_is_three stdout ----
task 'test_is_three' failed at 'One is not three', fizzbuzz.rs:8


failures:
test_is_three

result: FAILED. 0 passed; 1 failed; 0 ignored
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

rust: task failed at 'Some tests failed', /build/src/rust-0.6/src/libstd/test.rs:104
rust: domain main @0x85d9c0 root task failed
task '<main>' failed at 'Some tests failed', /some/path/to/rust

Rust is kind enough to give us a warning: we never used the `num`
argument. We then get our failure, "One is not three", because we
@@ -104,7 +109,7 @@ TDD means do the simplest thing! Compile and run it:
running 1 test
test test_is_three ... ok

result: ok. 1 passed; 0 failed; 0 ignored
result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

Awesome! We pass! We still have that warning, though... let's write
another test, and see what happens:
@@ -137,16 +142,20 @@ another test, and see what happens:
$ ./fizzbuzz
running 2 tests
test test_is_three_with_not_three ... ok
rust: task failed at 'Three should be three', fizzbuzz.rs:15
test test_is_three_with_three ... FAILED

failures:

---- test_is_three_with_three stdout ----
task 'test_is_three_with_three' failed at 'Three should be three', fizzbuzz.rs:15


failures:
test_is_three_with_three

result: FAILED. 1 passed; 1 failed; 0 ignored
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured

rust: task failed at 'Some tests failed', /build/src/rust-0.6/src/libstd/test.rs:104
rust: domain main @0x15109c0 root task failed
task '<main>' failed at 'Some tests failed', /some/path

Great! It showed that our first test passed, and that our second one
failed. Let's make both tests pass:
@@ -181,7 +190,7 @@ failed. Let's make both tests pass:
test test_is_three_with_not_three ... ok
test test_is_three_with_three ... ok

result: ok. 2 passed; 0 failed; 0 ignored
result: ok. 2 passed; 0 failed; 0 ignored; 0 measured

Awesome! This shows off how elses work, as well. It's probably what you
expected. Go ahead and try to refactor this into a one-liner.
@@ -199,17 +208,20 @@ but there's one wrinkle: note there's no semicolon here. If you had one,
you'd get:

$ rustc --test fizzbuzz.rs
fizzbuzz.rs:1:0: 3:1 error: not all control paths return a value
fizzbuzz.rs:1 fn is_three(num: int) -> bool {
fizzbuzz.rs:2 num % 3 == 0;
fizzbuzz.rs:3 }
hello.rs:2:21: 2:21 note: consider removing this semicolon:
hello.rs:2 num % 3 == 0;
^
hello.rs:1:5: 3:6 error: not all control paths return a value
hello.rs:1 fn is_three(num: int) -> bool {
hello.rs:2 num % 3 == 0;
hello.rs:3 }
error: aborting due to previous error

Basically, ending an expression in Rust with a semicolon ignores the
value of that expression. Another way to think about it is that the
semicolon turns the expression into a statement, and statements don't
have values. This is kinda weird. I don't know how I feel about it. But
it is something you should know about.
have values. This is kinda weird. It becomes natural after some use, though.
And Rust is even smart enough to tell us that it's probably a problem!

Okay, now try to TDD out the `is_five` and `is_fifteen` methods. They
should work the same way, but this will let you get practice actually
@@ -225,13 +237,15 @@ writing it out. Once you see this, you're ready to advance:
test test_is_three_with_three ... ok
test test_is_fifteen_with_not_fifteen ... ok

result: ok. 6 passed; 0 failed; 0 ignored
result: ok. 6 passed; 0 failed; 0 ignored, 0 measured

Okay! Let's talk about the main program now. We've got the tools to
build FizzBuzz, let's make it work. First thing we need to do is print
out all the numbers from one to 100. It's easy!

~~~ {.rust}
use std::io::println;
fn main() {
for num in range(0,100) {
println("num");
@@ -298,6 +312,8 @@ you're into that sort of thing.
Anywho, where were we? Oh, iteration:

~~~ {.rust}
use std::io::println;
fn main() {
for num in range(0, 100) {
println(num);
@@ -322,6 +338,8 @@ it a number. Whoops! Now, there's two ways to fix this. The first is to use the
`to_str` function:

~~~ {.rust}
use std::io::println;
fn main() {
for num in range(1, 100) {
println(num.to_str())
@@ -344,6 +362,8 @@ the `format!` function. At least, it looks like a function to me. Here it
is:

~~~ {.rust}
use std::io::println;
fn main() {
for num in range(1, 4) {
println(format!("{:d}", num));
@@ -368,6 +388,10 @@ Because this combination is common, you can use `println!` as a combination of
}
~~~

Note that we removed the import statement: we're no longer using the `println` from
the `io` module, we're using the `println!` macro from the 'prelude', which are
the things Rust automatically imports for you.

Anyway, now we have 1 to 99. We need 1 to 100.

~~~ {.rust}

1 comment on commit 9e55c57

@alan-andrade
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.