Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example listing-09-13 works even using Guess { value: guess } instead Guess::new(guess) #3748

Open
tomaslucas opened this issue Oct 12, 2023 · 1 comment

Comments

@tomaslucas
Copy link

tomaslucas commented Oct 12, 2023

  • I have searched open and closed issues and pull requests for duplicates, using these search terms:
    • listing-09-13
    • listing 09-13
    • 9-13
  • I have checked the latest main branch to see if this has already been fixed, in this file:
    • Yes

URL to the section(s) of the book with this problem:
https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html
https://github.com/rust-lang/book/blob/main/listings/ch09-error-handling/listing-09-13/src/main.rs
Description of the problem:
The text under the example says:

This public method is necessary because the value field of the Guess struct is private. It’s important that the value field be private so code using the Guess struct is not allowed to set value directly: code outside the module must use the Guess::new function to create an instance of Guess, thereby ensuring there’s no way for a Guess to have a value that hasn’t been checked by the conditions in the Guess::new function.

But if you call Guess { value: guess } instead Guess::new(guess) it works without errors.

Suggested fix:

use rand::Rng;
use std::cmp::Ordering;
use std::io;

use crate::guess_module::Guess;

// ANCHOR: here
pub mod guess_module {
    pub struct Guess {
        value: i32,
    }

    impl Guess {
        pub fn new(value: i32) -> Guess {
            if value < 1 || value > 100 {
                panic!("Guess value must be between 1 and 100, got {}.", value);
            }

            Guess { value }
        }

        pub fn value(&self) -> i32 {
            self.value
        }
    }
}
// ANCHOR_END: here

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1..=100);

    loop {
        println!("Please input your guess.");

        let mut guess = String::new();

        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read line");

        let guess: i32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        // This way to create a guess will work
        let guess = Guess::new(guess);
        // If you uncomment the next line instead the previous one we will have an error
        // let guess = Guess { value: guess };

        match guess.value().cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}
@tomaslucas tomaslucas changed the title Example listing-09-13 work even using Guess { value: guess } instead Guess::new(guess) Example listing-09-13 works even using Guess { value: guess } instead Guess::new(guess) Oct 12, 2023
@chriskrycho
Copy link
Contributor

Hi @tomaslucas, thanks for the issue! You're correct: we are not actually wrapping that in a module so it is not private. I've flagged this up for us to tackle in working on the 2024 revision.

@chriskrycho chriskrycho added this to the ch9 milestone Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants