ひさびさに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になってしまい、起点<終点というアサーションに失敗したというエラーが表示される。ただし、その後の処理はエラーにならないので、湯婆婆は発音できない名前を与えてくれます。

