XXX II

// XXX: old_io is probably facing deprecation if names mean anything
#![feature(old_io)]
use std::old_io;
use std::collections::HashMap;

fn main() {
    let things_to_ask_about = ["name", "age", "username"];
    let mut collected_information = HashMap::new();
    for askable in things_to_ask_about.iter() {
        println!("What is your {}?", askable);
        let input = old_io::stdin()
            .read_line()
            .ok().expect("failure message here");
        // XXX EVIDENCE OF MY IMPENDING DEATH in these moments when I
        // want to scream with the righteous fury of a person who has
        // been genuinely wronged, on the topic of what the fuck is wrong
        // with this bullshit language where you can't even trim a string
        // because "`input` does not live long enough" this and "borrowed
        // value is only valid for the block suffix following statement 1
        // at 21:48" that
        //
        // But what the fuck is wrong with this bullshit language is in
        // the map, not the territory
        //
        // on the balance of available evidence, doesn't it seem more
        // likely that the borrow checker is smarter than you, or that
        // the persons who wrote the borrow checker are smarter than you?
        //
        // and if you can't even follow their work even after several
        // scattered hours of dutifully trying to RTFM, will an
        // increasingly competitive global Economy remain interested in
        // keeping you alive and happy in the decades to come?
        //
        // I am not a person who has been genuinely wronged, just a man
        // not smart enough to know any better
        collected_information.insert(askable, input.trim());
    }

    for (askable, response) in collected_information.iter() {
        println!("You claimed that your {} is {}.", askable, response);
    }
}

4 thoughts on “XXX II

  1. Hey, just found this today.

    The issue is this line:

    collected_information.insert(askable, input.trim());

    since `trim()` returns a reference to `input`, when the next iteration of the loop happens, `input` goes away, meaning you have a HashMap full of dangling pointers. I haven't compiled this, but

    collected_information.insert(askable, input.trim().to_string));

    should take that reference to a string and convert it to a String of its own. Which makes it work.

  2. Paraphrasing an irc discussion:

    The problem here is that input.trim() gives you a &str, which is a reference into the input. So 'collected_information.insert(askable, input.trim())' would put a reference to the input into the map; but these can't live longer than `input`, which dies at the end of the for block.

    To actually store the value in the map, you need to copy it into the heap, with `collected_information.insert(askable, input.trim().to_string())`. This will create a String, which is basically (data_ptr, length, capacity) where data_ptr is a pointer to a heap-allocated char array.

    You can't put an arbitrary length char array into a map as a value because each value in the hashmap must have the same size; Strings (not the underlying char array, but the struct itself) are of course all the same size.

    So yes, the borrow checker is right, and this is just one of the bumps you have to go through when switching from a Heap-based language to a Stack-based one.

    (apparently the #rust channel on irc.mozilla.org is super-helpful, as I got this clarified within 30 seconds. Great thanks to steveklabnik from there!)

Leave a Reply

Your email address will not be published. Required fields are marked *