ひさびさにQiitaを開いてみたら、@Nemesisさんの「Javaで湯婆婆を実装してみる」という記事を読んだ。自称・ジブリファンとして、ここは私もオマージュを投稿してみたい。多分誰もやらなさそうな、超どマイナー言語・Valaで……
コード
public class Yubaba {
public static int main (string[] args) {
stdout.printf ("契約書だよ。そこに名前を書きな。\n");
string name = stdin.read_line ();
stdout.printf ("フン。%sというのかい。贅沢な名だねぇ。\n", name);
int new_name_index = GLib.Random.int_range (0, name.char_count ());
string new_name = name.get_char (name.index_of_nth_char (new_name_index)).to_string ();
stdout.printf ("今からお前の名前は%sだ。いいかい、%sだよ。分かったら返事をするんだ、%s!!\n", new_name, new_name, new_name);
return 0;
}
}
Ubuntu系であれば
$ sudo apt install -y valac libglib2.0-dev
でコンパイラとライブラリをインストールしてあげて
$ valac ./yubaba.vala
$ ./yubaba
で動く。
解説
標準入力という契約書
stdout.printf ("契約書だよ。そこに名前を書きな。\n");
string name = stdin.read_line ();
stdout.printf ("フン。%sというのかい。贅沢な名だねぇ。\n", name);
stdin.read_line ()
で名前を取得し、変数name
に代入。
名前を奪う
int new_name_index = GLib.Random.int_range (0, name.char_count ());
string new_name = name.get_char (name.index_of_nth_char (new_name_index)).to_string ();
Valaの標準ライブラリであるGLibにはRandom
という名前空間があり、int_range
というメソッドが用意されているので、それを使う。
引数には、起点(1文字目)と、終点(name
の文字数)を渡してあげます。注意したいのは、name.length
だとname
のバイト数が取得されてしまい、name
が全角文字の場合に正しく文字を抽出できないので、char_count
メソッドを使うという点1。
new_name_index
を用いて取り出した1文字はunichar型(32 bitのUnicode文字型)なので、string型に変換する。
名前を与える
stdout.printf ("今からお前の名前は%sだ。いいかい、%sだよ。分かったら返事をするんだ、%s!!\n", new_name, new_name, new_name);
標準出力で新しい名前を表示。new_name, new_name, new_name
が冗長なのなんとかならないだろうか……
実行結果
おまけ
なんも入力しないと、int_range
メソッドの引数が両方とも0になってしまい、起点<終点というアサーションに失敗したというエラーが表示される。ただし、その後の処理はエラーにならないので、湯婆婆は発音できない名前を与えてくれます。