Skip to content

Commit

Permalink
Tech review comments on ch7
Browse files Browse the repository at this point in the history
  • Loading branch information
carols10cents committed Jun 17, 2022
1 parent 95e9311 commit 961a816
Showing 1 changed file with 40 additions and 60 deletions.
100 changes: 40 additions & 60 deletions nostarch/chapter07.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ package but bigger than a module"... "reusable" or "what you specify as a
dependency" only applies to library crates... this definition I've added here
gets a little bit into how the compiler sees crates, which might be too much
detail? What do you think about this next paragraph? /Carol -->
<!-- JT, what do you think? /LC -->
<!-- I think this works.
Carol - I'm wondering a bit if "packages" above helps the reader build the mental
model or if it's kind of an implementation detail for cargo (we could say we "package
crates"). You're definitely the expert here, but I wonder if we can simplify down to
Crates/Modules/Paths and mention that we'll introduce some of the techniques
the tooling uses to work with these later. /JT -->

A *crate* is the smallest amount of code that the Rust compiler considers at a
time. Even if you run `rustc` rather than `cargo` and pass a single source code
Expand Down Expand Up @@ -97,9 +105,6 @@ package also contains a library crate that the binary crate depends on. Other
projects can depend on the Cargo library crate to use the same logic the Cargo
command-line tool uses.

<!-- can you give an example of a package like you did for the crates? /LC -->
<!-- Done! /Carol -->

A package can contain as many binary crates as you like, but at most only one
library crate. A package must contain at least one crate, whether that’s a
library or binary crate.
Expand All @@ -117,6 +122,9 @@ $ ls my-project/src
main.rs
```

<!-- I can't remember if we warned folks we were going to use unix commands. May
want to throw in the Windows command here too, so they feel welcome. /JT -->

After we run `cargo new`, we use `ls` to see what Cargo creates. In the project
directory, there’s a *Cargo.toml* file, giving us a package. There’s also a
*src* directory that contains *main.rs*. Open *Cargo.toml* in your text editor,
Expand Down Expand Up @@ -146,22 +154,7 @@ detail.

### Modules Cheat Sheet

<!-- Liz: Should this be a box or just a section? Is this header good? "Cheat
sheet" is another way I've been thinking of this.
The problem I'm trying to solve with this new section is that people often run
into problems with modules and they're looking for a short explanation of what
the compiler's rules are, and we didn't have that before. So I want to put the
sort of content those folks are looking for front and center. /Carol -->

<!--- Hmm, I like the idea of making this a cheat sheet. I'm torn on the box;
on the one hand I think it's great core content and usually we'd just make that
regular section; on the other, if we name it cheat sheet, it would be good to
make that content stand out in a way that groups it together, so a box would be
good. I think for now let's leave ourselves a note to address this when we lay
it out in the Word files, and I'll ask our production editor what they think...
/LC -->
<!-- Sounds good! /Carol -->
<!--WHEN TRANSFERRED TO WORD, DECIDE ON BOX OR NOT -->

Here we provide a quick reference on how modules, paths, the `use` keyword, and
the `pub` keyword work in the compiler, and how most developers organize their
Expand All @@ -171,28 +164,40 @@ work.

- **Start from the crate root**: When compiling a crate, the compiler first
looks in the crate root file (usually *src/lib.rs* for a library crate or
*src/main.rs* for a binary crate).
*src/main.rs* for a binary crate) for things to compile.
<!-- I may be asking a silly question here... but what is the compiler looking
for in the crate root file? just things to start compiling? /LC -->
<!-- That's exactly it-- it's the starting point of compilation, and the
compiler will only find files if they're connected to the crate root somehow.
Do you think that should be mentioned here? Is there something about this
explanation that would make you feel more confident about the concept? /Carol
-->
<!-- I've added "for things to compile" -- I wanted to make sure the reader
knew they weren't missing anything, that there wasn't a particular thing
being looked for that the reader wasn't aware of /LC -->
- **Declaring modules**: In the crate root file, you can declare new modules;
say, you declare a “garden” module with `mod garden;`. The compiler will look
for the module’s code in these places:
<!-- as in, the compiler will look for the module code in these places? I wasn't
sure what you meant by "will look for the code inside the module" /LC -->
<!-- Yes, the code definitions that go in the module. Is "the module's code"
clearer? /Carol -->

- Inline, directly following `mod garden`, within curly brackets instead of
the semicolon
<!-- instead of after the semicolon? Or is all of this instead of a
<!-- instead of or after the semicolon? Or is all of this instead of a
semicolon? /LC -->
<!-- Curly brackets and everything within them instead of the semicolon.
I'm not sure a pithy way to make that distinction clearer? /Carol -->
<!-- JT, would "Inline, within curly brackets that replace the semicolon following
`mod garden` be clearer/accurate? /LC -->
<!-- I wonder if we should order it where this cheatsheet happens after
we show more examples. Most of the time, you'll use the `mod` keyword to pull
files in as you refactor out into separate files. Sometimes you'll use it for
those key cases, like grouping tests. Showing those examples and then
going into the resolution may be a bit easier.
To your question - I think of this as something that could be more of
a warning. If you want to use `mod foo`, then be sure you haven't already
declared a module called that in the current file. If you do, the compiler will
see it first before it looks for a file with that name. /JT -->

- In the file *src/garden.rs*
- In the file *src/garden/mod.rs*
- **Declaring submodules**: In any file other than the crate root, you can
Expand All @@ -207,7 +212,7 @@ clearer? /Carol -->
refer to code in that module from anywhere else in that same crate, as long
as the privacy rules allow, using the path to the code. For example, an
`Asparagus` type in the garden vegetables module would be found at
`crate::garden::vegetables::Asparagus`.
`crate::garden::vegetables::Asparagus`.
- **Private vs public**: Code within a module is private from its parent
modules by default. To make a module public, declare it with `pub mod`
instead of `mod`. To make items within a public module public as well, use
Expand Down Expand Up @@ -274,11 +279,6 @@ module is private by default. Private items are internal implementation details
not available for outside use. We can choose to make modules and the items
within them public, which exposes them to allow external code to use and depend
on them.
<!-- are we saying we apply the public or private designation to an entire
module at a time? /LC -->
<!-- Not really, specific types and fields can be public or private. I think I
was trying to get at modules being private by default here; I've reworded to
hopefully clarify? /Carol -->

As an example, let’s write a library crate that provides the functionality of a
restaurant. We’ll define the signatures of functions but leave their bodies
Expand Down Expand Up @@ -412,6 +412,9 @@ pub fn eat_at_restaurant() {
}
```

<!-- We should probably let the reader know the above is expected to fail a little
earlier. /JT -->

Listing 7-3: Calling the `add_to_waitlist` function using absolute and relative
paths

Expand Down Expand Up @@ -440,8 +443,7 @@ absolute path to `add_to_waitlist`, but the relative path would still be valid.
However, if we moved the `eat_at_restaurant` function separately into a module
named `dining`, the absolute path to the `add_to_waitlist` call would stay the
same, but the relative path would need to be updated.
<!-- below: your preference in general, or for this example? /LC -->
<!-- in general, I've added /Carol -->

Our preference in general is to specify absolute paths because it’s more likely
we’ll want to move code definitions and item calls independently of each other.

Expand Down Expand Up @@ -568,8 +570,6 @@ only lets code in its ancestor modules refer to it, not access its inner code.
Because modules are containers, there’s not much we can do by only making the
module public; we need to go further and choose to make one or more of the
items within the module public as well.
<!-- so what can the ancestor do with hosting, at this point? /LC -->
<!-- Not much; I've added a sentence above to clarify that, hopefully? /Carol -->

The errors in Listing 7-6 say that the `add_to_waitlist` function is private.
The privacy rules apply to structs, enums, functions, and methods as well as
Expand Down Expand Up @@ -629,20 +629,13 @@ crate. These considerations are out of the scope of this book; if you’re
interested in this topic, see The Rust API Guidelines at
*https://rust-lang.github.io/api-guidelines/*.

<!-- Liz: This new box is a situation many readers have had problems with that
I wanted to add a bit of a call-out for. /Carol -->
<!-- Great idea /LC -->

> #### Best Practices for Packages with a Binary and a Library
>
> We mentioned a package can contain both a *src/main.rs* binary crate root as
> well as a *src/lib.rs* library crate root, and both crates will have the
> package name by default. Typically, packages with this pattern of containing
> both a library and a binary crate will have just
<!-- is "this pattern" having both these crates as package root? /LC -->
<!-- No... there's one package that contains two crates, and each crate has its
own root (there isn't a concept of "package root"). I've changed "this pattern"
to hopefully disambiguate a bit? /Carol -->
> enough code in the binary crate to start an executable that calls code with
> the library crate. This lets other projects benefit from the most
> functionality that the package provides, because the library crate’s code can
Expand All @@ -663,16 +656,11 @@ to hopefully disambiguate a bit? /Carol -->

We can construct relative paths that begin in the parent module, rather than
the current module or the crate root, by using `super` at the start of the
path. This is like starting a filesystem path with the `..` syntax. This allows
path. This is like starting a filesystem path with the `..` syntax. Using `super` allows
us to reference an item that we know is in the parent module, which can make
rearranging the module tree easier when the module is closely related to the
parent, but the parent might be moved elsewhere in the module tree someday.

<!-- can you lay out the problem it's solving explicitly, up front? That will
make it easier to follow the example. Are we defining relationships between
functions using super? /LC -->
<!-- Done /Carol -->

Consider the code in Listing 7-8 that models the situation in which a chef
fixes an incorrect order and personally brings it out to the customer. The
function `fix_incorrect_order` defined in the `back_of_house` module calls the
Expand Down Expand Up @@ -1188,12 +1176,10 @@ file to make the code easier to navigate.
this section a bit; some readers ended up with code that didn't compile because
the last explanation wasn't as clear as it could have been. Please do try
following these instructions! /Carol -->
<!-- JT, leaving this here for you so you can see what's new /LC -->

For example, let’s start from the code in Listing 7-17 that had multiple
restaurant modules. We’ll
<!-- can you remind us of the state of 7-17, since we've seen a couple of other
listings since then? /LC -->
<!-- Done! /Carol -->
extract modules into files instead of having all the modules defined in the
crate root file. In this case, the crate root file is *src/lib.rs*, but this
procedure also works with binary crates whose crate root file is *src/main.rs*.
Expand Down Expand Up @@ -1253,6 +1239,8 @@ named for its place in the module tree? Aren't they all? /LC -->
<!-- The distinction I'm trying to emphasize here is that the first level of
submodules go in *src*, but the next level (and further levels) of modules need
to go in subdirectories. I've tried to reword a bit, is this better? /Carol -->
<!-- JT, is this all clear? /LC -->
<!-- All clear for me /JT -->

To start moving `hosting`, we change *src/front_of_house.rs* to contain only the
declaration of the `hosting` module:
Expand All @@ -1278,17 +1266,11 @@ root, and not delcared as a child of the `front_of_house` module. The
compiler’s rules for which files to check for which modules’ code means the
directories and files more closely match the module tree.

<!-- Liz: This new box is a topic some readers were surprised wasn't covered at
all, so I wanted to put in a quick mention because some people prefer this
structure even though it's not what most projects do. /Carol -->

> ### Alternate File Paths
>
> So far we’ve covered the most idiomatic file paths the Rust compiler uses,
> but Rust also supports an older style of file path. For a module named
<!-- do you mean an older style of file path? or older as in where the file
used to be? /LC -->
<!-- Ah yes, this is an older *style*. I've clarified /Carol -->
> `front_of_house` declared in the crate root, the compiler will look for the
> module’s code in:
>
Expand All @@ -1302,9 +1284,7 @@ used to be? /LC -->
> * *src/front_of_house/hosting/mod.rs* (older style, still supported path)
>
> If you use both styles for the same module, you’ll get a compiler error. Using
<!-- use both paths? or use a mix of styles for the same module, you mean? /LC -->
<!-- A mix of styles, I've added that word in /Carol -->
> both styles for different modules in the same project is allowed, but
> a mix of both styles for different modules in the same project is allowed, but
> might be confusing for people navigating your project.
>
> The main downside to the style that uses files named *mod.rs* is that your
Expand Down

0 comments on commit 961a816

Please sign in to comment.