2019/01/09

変数を扱えるようになったumeboshi

グローバルでミュータブルなHashMap

遅めですが、皆様あけましておけでとうございます。今年も皆様にとって、良い一年になりますように。
年末年始はダラダラとしてしまいがちですが、私今回は酒も呑まず、いつものように勉強しつつ、コードを書いて、試行錯誤して年を越しました。
年末に思い立った「umeboshi」で変数を扱いたいという思いがそうさせたのですが、とりあえず不格好ではあるものの、なんとか形にできたので、記事を書きました。

Rustでは仕様上、グローバルでミュータブルなものをなんとかとか使わせないようにしようとします。これは、このようなものがあまり安全ではなく、また各パーツが密に結合してしまうからです。すごく徹底しています。
今回umeboshiで、そのようなグローバルでミュータブルなものが使えたらいいなぁと思い、色々調べていましたら、クレートlazy_staticとstd::sync::RwLockを使えば、できそうだったので、試しに実践してみました。umeboshiのコードはGitHubに置いていますので、ここでは部分的に取り上げます。

lazy_static! {
    static ref VARS: RwLock<HashMap<String, String>> = {
        let mut vars = HashMap::new();
        vars.insert("default".to_string(), "None".to_string());
        RwLock::new(vars)
    };
}

// Get value from varibable name.
fn getv(key: String) -> Option<String> {
    let vars = VARS.read().unwrap();
    match vars.get(&key) {
        Some(r) => Some(r.to_string()),
        None => None
    }
}

// Set variable.
fn setv(key: String, value: String) {
    let mut vars = VARS.write().unwrap();
    vars.insert(key, value);
}
Twitterのほうで、正しいかどうか質問してみたところ、ロジックのバグは別の話だけれど、コンパイラがとおしているならば、コード上は問題ないという回答をいただきました。ロジックのバグ……いっぱいありそうです……
そのあたりはもっと勉強して、最終的に良い形にもっていければと思います。そもそもの設計ミスは多分にあることでしょう。しかしながら、現在とりあえずは機能しております。

今年の抱負

今年は、年末に発見したPonylangの勉強や時々練習していたCommon Lispをちゃんと使えるように勉強していこうと思います。また去年あまり使っていなかったPythonも忘れることがないように、時々使おうと思います(まだ一応覚えている、よかった)