9
2

More than 3 years have passed since last update.

Gleamで湯婆婆を実装してみる

Last updated at Posted at 2020-11-22

1.はじめに

令和時代の"Hello world"と呼ばれる(?)湯婆婆実装シリーズに便乗してみました。

この記事では、Gleamという言語での実装にチャレンジしました。

Gleamについてご存じない方は、こちらを参照頂けると幸いです。
→ Gleam (Rust + Erlang) 事始め

2.実装例

(1)プロジェクトの作成

コマンドライン
$ gleam new yubaba
* creating yubaba/LICENSE
* creating yubaba/.gitignore
* creating yubaba/README.md
* creating yubaba/gleam.toml
* creating yubaba/test/yubaba_test.gleam
* creating yubaba/src/yubaba.gleam
* creating yubaba/.github/workflows/test.yml
* creating yubaba/rebar.config
* creating yubaba/src/yubaba.app.src

Your Gleam project "yubaba" has been successfully created.
The rebar3 program can be used to compile and test it.

    cd yubaba
    rebar3 eunit

(2)コード

標準入力の関数が無いようなので、名前の入力は、関数の引数に直接与えています。

また、”名前を奪う”ために、ランダムにN文字目を取り出す処理が、かなり回りくどい書き方になってます・・・

src/yubaba.gleam
import gleam/float
import gleam/int
import gleam/io
import gleam/result
import gleam/string

pub fn hello_world() -> String {
  "Hello, from yubaba!"
}

//0.0~1.0の間でFloat型の乱数を返す
//https://gleam.run/book/tour/external-functions.html
pub external fn random_float() -> Float = "rand" "uniform"

//湯婆婆関数
pub fn yubaba(name:String) {

  //文字の長さを取得
  let name_length = int.to_string(string.length(name))

  //何文字目を切り出すか乱数で決める:その1
  //※to_float関数がまだ実装されてないのでダメでした
  //  https://hexdocs.pm/gleam_stdlib/gleam/int/#to_float
  //let name_num = int.to_float(name_length) *. name_length

  //何文字目を切り出すか乱数で決める:その2
  //※回りくどいけど、なんとかできた・・・

  //”文字列の長さの値”を、一旦文字列に変換して、小数点を付ける
  let length_1 = string.concat([name_length, ".0"])
  //”小数点付きの文字列長”の文字列を、floatに変換。unrap関数で値と成功/失敗値を分割
  let length_2 = result.unwrap(float.parse(length_1), 0.0)
  //乱数の値と、文字列長を掛けて、何文字目を取り出すかを決める
  let name_num = float.round(float.floor(random_float() *. length_2))

  //名前を1文字切り出す
  let name_new = string.slice(from: name, at_index: name_num, length: 1)

  //湯婆婆のメッセージ
  io.println("\n■■■ Gleamで湯婆婆を実装してみる ■■■\n")
  io.println("契約書だよ。そこに名前を書きな。\n")
  io.println(string.concat([" > ", name, "\n"]))
  io.println(string.concat(["フン。", name, "というのかい。贅沢な名だねぇ。\n"]))
  io.println(string.concat(["今からお前の名前は", name_new, "だ。いいかい、",
      name_new, "だよ。分かったら返事をするんだ、" , name_new, "!!\n"]))

  //何文字目を切り取ったかの値を返す
  name_num
}

(3)実行例

  1. rebar3 shellでコンパイル、対話モードに入ります。
  2. プロンプトにyubaba:yubaba("yourname").を入力してEnterします。(今回の実装だと、全角はだめっぽい)
  3. 湯婆婆に名前を奪われます。
コマンドライン
$ rebar3 shell
===> Verifying dependencies...
Compiling gleam/otp/port
・・・(省略)・・・
Done!
===> Analyzing applications...
===> Compiling yubaba
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V10.5.4  (abort with ^G)

1> yubaba:yubaba("myasu").  
■■■ Gleamで湯婆婆を実装してみる ■■■
契約書だよ。そこに名前を書きな。
 > myasu
フン。myasuというのかい。贅沢な名だねぇ。
今からお前の名前はaだ。いいかい、aだよ。分かったら返事をするんだ、a!!
2

2> yubaba:yubaba("myasu").
■■■ Gleamで湯婆婆を実装してみる ■■■
契約書だよ。そこに名前を書きな。
 > myasu
フン。myasuというのかい。贅沢な名だねぇ。
今からお前の名前はyだ。いいかい、yだよ。分かったら返事をするんだ、y!!
1

3> yubaba:yubaba("pomu"). 
■■■ Gleamで湯婆婆を実装してみる ■■■
契約書だよ。そこに名前を書きな。
 > pomu
フン。pomuというのかい。贅沢な名だねぇ。
今からお前の名前はuだ。いいかい、uだよ。分かったら返事をするんだ、u!!
3

4.まとめ

Gleamの勉強がてら(?)試してみました。
悩ましいところが多々あるので、ぼちぼちと直していきます・・・

参考資料

9
2
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
9
2