Clojure Tutorial Part 4 -- string ライブラリを使ってみる
Tags: clojure
Published: 2022-06-01 15:23:47

## 参考

https://clojure.org/guides/repl/basic_usage#_example_using_clojure_string

Clojure の公式チュートリアル
basic-usage の string 編。

---

## string のライブラリを読み込んで upper-case を試す

今回も clj コマンドでターミナルで CLI を動かす

```clj
( require '[clojure.string])
(clojure.string/upper-case "abCd")
"ABCD"
```

数値の計算と違って、require でライブラリを呼び出す必要がある
Django REST Framework とターミナルで使った時と似ている

しかし、JS や PY とは違って 'library/detail' のように
シングルクォートで括ることはしない。始まりだけだ。終わりはない。
終わりなき戦いが始まる、そういうメッセージなのかもしれない。

https://stackoverflow.com/a/34118964

そんなことはなくて名前空間のシンボルになっているだけだった。

そして require でインポートした ライブラリとその中身の関数を
四則演算のように使って引数を処理する。ただし引数はいつも 1 つ！

---

## :as を使ってライブラリ名を別名で import する

```clj
(require '[clojure.string :as customName])
(customName/upper-case "hoge")
"HOGE"
```

ライブラリ名は `:as` を使うことで自由な名前で import できる。
関数名は変えられないと予想。

---

## :refer [function-name] で関数を直接呼び出せるようにする　

```clj
(require '[clojure.string :refer [upper-case]])
(upper-case "toUpperCaseOnly")
"TOUPPERCASEONLY"
```

`:refer [function-name]` を使うことで
ライブラリの中の関数のみ
四則演算の関数 (+,-) のように使うことができるようになる。

---

## エラーが起きる事例

```clj
 (upper-case "toUpperCaseOnly" "second value" "Third Value")
Execution error (ArityException) at user/eval17 (REPL:1).
```

複数の引数をまとめて処理することはできない。

```clj
(upper-case 'single')
"SINGLE'"
```

JS と違ってシングルクォートは括ったものを文字列とみなす処理にはならない。
括れないという点では : (コロン) と似たような扱いなのだろうか？

---

## :refer と :all で関数を全て import する

```clj
(upper-case "quote")
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: upper-case in this context

user=> (require '[clojure.string :refer :all])
WARNING: reverse already refers to: #'clojure.core/reverse in namespace: user, being replaced by: #'clojure.string/reverse
WARNING: replace already refers to: #'clojure.core/replace in namespace: user, being replaced by: #'clojure.string/replace
nil

user=> (upper-case "quote")
"QUOTE"
```

:all を使えば全て　import できるが、
既に読み込まれている？ core の reverse と replace を
上書きしてしまうため、やたらと :all は使わない方がいいらしい。

---

## repl の dir 関数で string 関数の中身を全て出す

```clj
(require '[clojure.repl :refer :all])

(dir clojure.string)
blank?
capitalize
ends-with?
escape
includes?
index-of
join
last-index-of
lower-case
re-quote-replacement
replace
replace-first
reverse
split
split-lines
starts-with?
trim
trim-newline
triml
trimr
upper-case
```

repl の dir を使って string の中身の関数を全て並べると

JS でお馴染みの 

* join
* sprit
* reverse
* replace
* trim
* ends-with

などがあった

ちなみに同じく repl ライブラリの

apropos, find-doc, doc を使えば関数とドキュメントを検索できて

```clj
source join)
(defn ^String join
  "Returns a string of all elements in coll, as returned by (seq coll),
   separated by an optional separator."
  {:added "1.2"}
  ([coll]
     (apply str coll))
  ([separator coll]
     (loop [sb (StringBuilder. (str (first coll)))
            more (next coll)
            sep (str separator)]
       (if more
         (recur (-> sb (.append sep) (.append (str (first more))))
                (next more)
                sep)
         (str sb)))))
```

source を使えばその関数の実際のソースコードが見れる。
さすが Lisp 族、研究者向けすぎる

---

## まとめ

```clj
( require '[clojure.string] )
```

この形でライブラリを import して

```clj
( clojure.string/upper-case "abCd" )
```

そのライブラリ名と中の関数名を指定することで
引数の文字列に関数を打つことができる。

string には `' '` は使えず、 `" "` のみしか使えない。
ダブルのみ。

string になんの関数があったっけ？
と忘れたときは repl/dir で一覧を出力できる。

upper-case ってなんだっけ？
と忘れたときは repl/doc で説明を出力できる。

repl/source を使えば実装のコードすら出力できる。

画期的。これはターミナルでの計算において、 Python より圧倒的に便利だ。