おっさんの挑戦(画像ビューア作成) 004
おっさんになると急激に理解力や記憶力が低下したことを感じる。
法月綸太郎氏の「頼子のために」を読んだ。
法月綸太郎氏が25歳の時、1987年初版刊行。もともとは大学生時代の中編に肉付けしたそうだ。最後がとても面白かった。
若い。羨ましい。すごい。
でもちょっと古い。体型の表現に「電話ボックス」、カセットテープの再生に「オートリバース」は、もう年齢を必要とする。
おっさんはついニヤッと気持ちの悪い笑みを浮かべてしまう。
前途洋々の若人のためにオートリバースについて書くと、
カセットテープは、CDなどと違って、任意の場所から再生させるには、磁器テープを巻いて移動させなければならない。
オートリバースは、最後まで再生したカセットテープを自動的に巻き戻して、最初から再生させる機能。
巻き戻すっていうのは、磁気テープを再生時とは逆方向に巻くことを指す。
だけど、この「オートリバース」って表現は、機械の機能についての呼び名であって、聴衆向けの表現ではない。
聴衆はテープの最初から再生するのだから、自動再生やリピート再生だよね。
こうした技術者寄りの表現も、時代ならではという気がする。
最近は、表現はずいぶん使い手寄りになったなぁと思う。
一方高機能すぎて、おっさんには使いこなせない。かちこち頭のおっさんには、新しいことに順応するのは難しいのだ。
Rust も豊富な機能を取り揃えていて、しかも cargo で楽に入手できる。
だけど高機能すぎて、なかなか使いこなせない。なんでまたコンパイルエラーなんだろう…。
std::path::Path を使って、表示する画像をコマンドライン引数で受け取るようにした。
複数の指定やディレクトリの指定もできた。
Next ボタンを追加して、指定した画像ファイルを順番に表示するようにした。
だけど、たったこれだけを実装するのに半日は費やした。
なにより所有権と、String, &Str などの違いがよくわかっていない。
概念は理解しているのだけど、結局所有権にまつわる問題を回避するために、ひたすら clone() している。
もっとそれぞれの動きを考慮して、これは参照で良い、と決めれば良いのだけど、自分で書いたコードのくせに追っていくのが難しい。
ともあれ、自分の能力の限界に応じて少しずつ進めていくしかない。
指定したファイル、ディレクトリ内のファイル名を Vec
シンボリックリンクをたどることはしていない。参照先のサブディレクトリに自分がいると循環してしまうから。
use std::ffi::OsString; use std::path::Path; #[derive(Debug, Clone)] // derive Debug, Clone trait struct Images { files: Vec<OsString>, index: usize, } impl Images { fn new(args: Vec<String>) -> Result<Self, &'static str> { let mut instance = Images { files: Vec::new(), index: 0, }; if args.len() < 2 { return Err("No files are specified"); } // for each argument, for arg in &args { for f in instance.file_or_files_in_dir(&OsString::from(arg), true) { instance.files.push(f); } } instance.files.remove(0); println!("{:?}", instance.files); Ok(instance) } // this function returns path strings of the spcified directory. fn file_or_files_in_dir(&mut self, path_str: &OsString, recursive: bool) -> Vec<OsString> { let mut files: Vec<OsString> = Vec::new(); let path = Path::new(path_str); if path.is_file() { files.push(path_str.clone()); } else if path.is_dir() { for child in path.read_dir().expect("read_dir call failed") { let child = child.unwrap(); if recursive { // a child directory is also expanded and pushed for f in self.file_or_files_in_dir(&child.path().into_os_string(), recursive) { files.push(f); } } else { // only file is pushed, dir and symlink are skipped if child.path().is_file() { files.push(child.path().into_os_string()); //file_name()); } } } } else { // SYMLINK // do nothing. we have never implement for circular reference } files } }