LoginSignup
0
0

More than 5 years have passed since last update.

べろろろろろろ

Last updated at Posted at 2019-05-02

まず Power shell をダブルクリックで起動できるようにしろだぜ☆

[ここを読む(https://qiita.com/muzudho1/items/3a5784faddfa77df99f9)

設定ファイルを探して設定しろ。

ディレクトリ構成を合わせろ。

リリース・ビルドだけでなく、デバッグ・ビルドも持っとけ。
リリース・ビルドで強制終了したら エラー原因が分からん。ログを吐く .exe 必須。

ログ吐く前に 強制終了してたら 設定ファイル読み込めてない可能性高い。

target
|
+-- release
|
+-- debug

特に設定していなければ rust の場合 cargo build で target/debug ディレクトリの下に .exe や .d が出力されている。
cargo build --release なら target/release。

.d はテキストファイルで開けば分かるが デバッグで使ってるだけなんで本番環境で要らない。

人間がボトルネック

当日の修正でバグを盛り込んでしまう。結果を見る前から 修正 という言葉を使うのは矛盾している。修正ではなく変更。

感情がない人というのは 1つ1つの感情表現が豊かな人に比べて 感情を細かく多めに使ってしまって 平坦になっている人のことだ。

ディレクトリー構成

テスト環境と、本番環境では ディレクトリーのここに置け、という制約が変わることがある。
だいたいConfigみたいな感じの名前の付いている設定ファイルがあると思うが、設定しても、
管理者権限や、パーミッションを別途 要求される場合があるので まず ドキュメント・ディレクトリーに配置して
そもそも 動くのか確認する。

全部絶対ファイルパスで書いてみる。

古いプログラムが動いていて、新しいプログラムが動かないのなら

プログラム言語の環境を 再インストール、アップデートだ!

rustup update

rustc --version

これでバージョンがそろってて、あとは何が違うのか。

調べてみると、 debug ビルドのものは動いて、 release ビルドのものは動かない。

たどっていくと、ディレクトリ構成が異なるのを認識し、
logs フォルダーが無いと強制終了するようになっている。

    /// Write line.
    pub fn println(&self, line: &str) {
        println!("{}", line);

        let mut file = OpenOptions::new()
            .create(true)
            .write(true)
            .append(true)
            .open(&self.log_file_name)
            .unwrap();

        if let Err(e) = writeln!(file, "{}", line) {
            eprintln!("Couldn't write to file: {}", e);
        }
    }

ファイルが無ければ上書きするが、ディレクトリーがない場合は .unwrap() で強制終了するのでエラーも吐かない。

    /// Write line.
    pub fn println(&self, line: &str) {
        println!("{}", line);

        // ディレクトリー作成。
        if let Some(parent) = Path::new(&self.log_file_name).parent() {
            match fs::create_dir_all(parent) {
                Ok(_x) => {}
                Err(err) => panic!(err),
            }
        } else {
            panic!("Create directory fail. {}", self.log_file_name);
        }

        let mut file = OpenOptions::new()
            .create(true)
            .write(true)
            .append(true)
            .open(&self.log_file_name)
            .unwrap();

        if let Err(e) = writeln!(file, "{}", line) {
            eprintln!("Couldn't write to file: {}", e);
        }
    }

OpenOption をぜんぶ検索して ディレクトリー作成コードを付けまくって応急処置。

.unwrap() とか適当に使ってると エラーが出ない。

.unwrap(); を機械的に .unwrap_or_else(|| panic!("")); に置き換えるとどうだろうか?
それでもログに残らないので、ログに残るように改造する。

panic! の代わりに形式上 String を返す関数を作り、その中で ログ取って、panic! する。

と思ったら、 unwrap_or_else の仕様はメソッドによってバラバラなようだ。

        let ext = get_extension_from_filename(&in_file)
            .unwrap_or_else(|| app.comm.panic_as_str("Fail. get_extension_from_filename."))
            .to_uppercase();

雰囲気的にはこんな感じで、戻り値の違うログ取りパニック関数を用意していく。

unwrap_or_panic() が欲しい。戻り値の種類は 有限だが山ほどある。

    /// panic! で包んで使う。
    pub fn panic(&self, msg: &str) -> String {
        self.println(msg); // コンソールに表示して、ログも取る。
        String::from(msg)
    }

こういう自作関数を作る。

    let file = args
        .output_file
        .unwrap_or_else(|| panic!(app.comm.panic("Fail. args.output_file.")));

こんな雰囲気で使う。

Result 型の .unwrap() を .unwrap_or_else() に変えるとなんかエラーが出る。

    /// 入出力エラーの時、 panic! で包んで使う。
    pub fn panic_io(&self, err: &std::io::Error) -> String {
        let msg = format!("{}", err);
        self.println(&msg);
        String::from(msg)
    }

こうすりゃいいのか。
しかし Error クラスはいっぱいある。 int型のパースの Error も別クラス。
rust のエラークラスの操作は統一されてないのか?

unwrap_or_else(|f| panic!(app.comm.panic(&f.to_string())))

.to_string() できるやつはこれでいける。

            let id: i8 = id_vec[i].parse().unwrap();

文字列、数値変換のときのパース失敗時のパニックのメッセージをログに取るのがむずかしい。

            let id: i8 = match id_vec[i].parse() {
                Ok(x) => x,
                Err(err) => panic!(app.comm.println(&format!("{}", id_vec[i]))),
            };

数値変換のたびに こんな長いの書きたくない。

            let id: i8 = id_vec[i]
                .parse()
                .unwrap_or_else(|err| panic!(app.comm.println(&format!("{}", err))));

短くしてこうか。

100個ほどの '.unwrap()' を '.unwrap(' で検索し、すべて '.unwrap_or_else' で書き直し
ログ出力するように2時間ほどで書き直し。

本番環境で release フォルダーに入れていたので ファイルパスが違っていたことが分かったので
release フォルダーの外に出したら動いた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0