user=> (+ 2 3)
5
user=> (defn factorial [n]
(if (= n 0)
1
(* n (factorial (dec n)))))
#'user/factorial
user=> (factorial 10)
3628800
user=>
REPLを起動したら(前の章で説明したように)、Clojure式をREPLに入力してEnterキーを押すだけで評価できます。
user=> (+ 2 3)
5
user=> (defn factorial [n]
(if (= n 0)
1
(* n (factorial (dec n)))))
#'user/factorial
user=> (factorial 10)
3628800
user=>
各式の結果には、式の評価結果が表示されます。これがREPLの機能です。REPLは、送信された式を**R**ead(読み込み)、**E**valuate(評価)、**P**rint(出力)し、これを**L**oop(ループ)で繰り返します。
Clojureの学習中であれば、REPLで実験する時間をとってください。REPLが提供する迅速なフィードバックループは、非常に効果的な学習環境となります。 |
上記の例は非常に基本的なものですが、この方法でフル機能のClojureプログラムを実行できます。Clojureは、REPL環境が言語の全機能を提供するように設計されています。既存のClojureプログラムであれば、ソースファイルの内容を正しい順序でREPLに貼り付けるだけで実行できます。
ヒント:REPLの隣でエディタを使用する ターミナルウィンドウ内でClojureコードを編集するのは面倒な場合があります。その場合は、構文認識Clojureモードを持つ任意のテキストエディタでコードを作成し、エディタからREPLターミナルウィンドウにコードをコピーアンドペーストするという簡単な方法があります。これがその例です(使用しているエディタはAtomです)。 このガイドのREPLワークフローの改善の章では、REPLを使用するためのより人間工学的な構成を見ていきます。ただし、この最小限の設定は、このチュートリアルの範囲には十分であり、基礎を習得するために重要です。 |
次の評価を考えてみましょう。
user=> (println "Hello World")
Hello World
nil
これは奇妙です。以前の例とは異なり、(println "Hello World")
式の評価では、Hello World
とnil
の2つの結果が得られたように見えます。
これは、println関数が引数を標準出力に出力するが、nil
を返すためです。したがって、式の下に表示される2行は性質が大きく異なります。
Hello World
は、式を評価することによる副作用(標準出力への出力)です。出力はコードによって行われました。
nil
は、式を評価した結果です。出力はREPLによって行われました。
これまで、REPLで手動で定義したコード(上記のfactorial
関数など)のみを呼び出していました。しかし、REPLでは、既存のClojureコード、つまりClojure ライブラリも使用できます。[1] 名前空間がmy.name.space
であるClojureライブラリの場合、(require '[my.name.space])
を評価することで、そのライブラリのコードをロードしてREPLで使用できます。
たとえば、clojure.string
は、テキストを操作するためのClojureにバンドルされているライブラリです。clojure.string
をrequireし、そのclojure.string/upper-case
関数を呼び出してみましょう。
user=> (require '[clojure.string])
nil
user=> (clojure.string/upper-case "clojure")
"CLOJURE"
require
では、:as
句を追加することで、clojure.string
名前空間のエイリアスを定義することもできます。これにより、clojure.string
名前空間に定義されている名前をより簡潔に参照できます。
user=> (require '[clojure.string :as str])
nil
user=> (str/upper-case "clojure")
"CLOJURE"
最後に、非常に面倒くさがりでエイリアスをまったく入力したくない場合は、:refer
句を追加できます。
user=> (require '[clojure.string :refer [upper-case]])
nil
user=> (upper-case "clojure")
"CLOJURE"
REPLは、clojure.repl
ライブラリを使用して、APIドキュメントを参照するためにも使用できます。REPLで次の式を評価します。
user=> (require '[clojure.repl :refer :all])
nil
この式により、clojure.repl
名前空間に定義されているすべての名前をREPLで使用できるようになります。
(doc MY-VAR-NAME)
を評価することで、指定されたVarのAPIドキュメントを出力できます。
user=> (doc nil?)
-------------------------
clojure.core/nil?
([x])
Returns true if x is nil, false otherwise.
nil
user=> (doc clojure.string/upper-case)
-------------------------
clojure.string/upper-case
([s])
Converts string to all upper-case.
nil
source
を使用して、Varの定義に使用されたソースコードを表示することもできます。
user=> (source some?)
(defn some?
"Returns true if x is not nil, false otherwise."
{:tag Boolean
:added "1.6"
:static true}
[x] (not (nil? x)))
nil
dir
を使用して、指定された名前空間に定義されているすべてのVarの名前を一覧表示できます。clojure.string
名前空間でこれを実行してみましょう。
user=> (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
nil
別の例として、dir
を使用してclojure.repl
自体で使用できるものを確認してみましょう。
user=> (dir clojure.repl)
apropos
demunge
dir
dir-fn
doc
find-doc
pst
root-cause
set-break-handler!
source
source-fn
stack-element-str
thread-stopper
nil
これまでに使用したdoc
、source
、dir
操作が認識できます。
Varの名前を正確に覚えていない場合は、apropos
を使用して検索できます。
user=> (apropos "index")
(clojure.core/indexed? clojure.core/keep-indexed clojure.core/map-indexed clojure.string/index-of clojure.string/last-index-of)
user=> (find-doc "indexed")
-------------------------
clojure.core/contains?
([coll key])
Returns true if key is present in the given collection, otherwise
returns false. Note that for numerically indexed collections like
vectors and Java arrays, this tests if the numeric key is within the
range of indexes. 'contains?' operates constant or logarithmic time;
it will not perform a linear search for a value. See also 'some'.
-------------------------
clojure.core/indexed?
([coll])
Return true if coll implements Indexed, indicating efficient lookup by index
-------------------------
clojure.core/keep-indexed
([f] [f coll])
Returns a lazy sequence of the non-nil results of (f index item). Note,
this means false return values will be included. f must be free of
side-effects. Returns a stateful transducer when no collection is
provided.
-------------------------
clojure.core/map-indexed
([f] [f coll])
Returns a lazy sequence consisting of the result of applying f to 0
and the first item of coll, followed by applying f to 1 and the second
item in coll, etc, until coll is exhausted. Thus function f should
accept 2 arguments, index and item. Returns a stateful transducer when
no collection is provided.
nil
ドキュメントは、requireされたライブラリについてのみ使用できます。 たとえば、
|