私は最近(技術のおかげで)REPL ---
これは失敗します:
user=> (:require [clojure.set :as set])
Java.lang.ClassNotFoundException: clojure.set (NO_SOURCE_FILE:24)
これが成功するところ:
user=> (require '[clojure.set :as cs])
nil
clojure.setクラスのロード時。
コンテキスト:前の行は名前空間付きのソースファイルからコピーされました。
私の主な質問は次のとおりです::と '文字を入れ替えることにより、後のコマンドを正常に実行できるようになりました。
私の2番目の質問は、一般的に-REPL ---通常のclojureソースファイルでの作業と比較して、作業を行うためのガイドラインは何ですか?ここで仮定しますLEININGENプロジェクトのルートからreplをロードできるため、少なくともjarはディスクの依存関係サブディレクトリで使用できます。
私は高レベルからあなたの特定の問題に行きます:
REPLまたはRead-Eval-Printループは、LISPの設計方法の中核です。
したがって、REPLにテキストを入力すると、これらの各ステップを実行して、入力を処理し、出力を端末に返します。
最初のいくつかは、clojureリーダーのフォームです。これは非常に簡潔です。 read またはそれについて( part 1 、 part 2 )をご覧になることをお勧めします。
Clojureのsymbolは、特定の値(変数など)を表すことができる形式です。シンボル自体をデータとして渡すことができます。これらはcのポインタに似ていますが、メモリ管理機能がありません。
コロンが前にある記号は、keywordです。キーワードはシンボルのようなものですが、キーワードの値は常にそれ自体であり、文字列や数値に似ています。それらはRubyのシンボルと同じです(これにもコロンが付いています)。
フォームの前のquoteは、データ構造をそのままにするように評価者に指示します。
user=> (list 1 2)
(1 2)
user=> '(1 2)
(1 2)
user=> (= (list 1 2) '(1 2))
true
引用はリスト以外にも適用できますが、clojureのエバリュエーターは通常、リストを関数のような呼び出しとして実行するため、リストに主に使用されます。 '
の使用は、引用マクロの省略形です。
user=> (quote (1 2)) ; same as '(1 2)
(1 2)
引用は基本的に、返す実際のコードではなく、返すデータ構造を指定します。したがって、シンボルを参照するシンボルを引用できます。
user=> 'foo ; not defined earlier
foo
そして、引用は再帰的です。したがって、内部のすべてのデータも引用されています。
user=> '(foo bar)
(foo bar)
引用せずに(foo bar)
の動作を取得するには、それを評価できます。
user=> (eval '(foo bar)) ; Remember, foo and bar weren't defined yet.
CompilerException Java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:1)
user=> (def foo identity)
#'user/foo
user=> (def bar 1)
#'user/bar
user=> (eval '(foo bar))
1
引用することは他にもたくさんありますが、それはこの範囲外です。
Requireステートメントについては、前者が次の形式で見つかったと想定しています。
(ns my.namespace
(:require [clojure.set :as set]))
ns
は マクロ で、:require式を、記述した後者の形式に変換します。
(require '[clojure.set :as set])
いくつかのネームスペース作業とともに。 REPLでnsのドキュメントを要求するときに、基本が説明されています。
user=> (doc ns)
-------------------------
clojure.core/ns
([name docstring? attr-map? references*])
Macro
Sets *ns* to the namespace named by name (unevaluated), creating it
if needed. references can be zero or more of: (:refer-clojure ...)
(:require ...) (:use ...) (:import ...) (:load ...) (:gen-class)
with the syntax of refer-clojure/require/use/import/load/gen-class
respectively, except the arguments are unevaluated and need not be
quoted. (:gen-class ...), when supplied, defaults to :name
corresponding to the ns name, :main true, :impl-ns same as ns, and
:init-impl-ns true. All options of gen-class are
supported. The :gen-class directive is ignored when not
compiling. If :gen-class is not supplied, when compiled only an
nsname__init.class will be generated. If :refer-clojure is not used, a
default (refer 'clojure) is used. Use of ns is preferred to
individual calls to in-ns/require/use/import:
一般に、REPLでns
を使用せず、require
関数とuse
関数を使用します。しかし、ファイルでは、ns
マクロを使用してこれらのことを行います。
違いは、require
はコードのインポートに使用される関数であるのに対し、:require
はキーワードです。
キーワードを関数として使用するとどうなるか覚えておいてください。
=> (type :require)
clojure.lang.Keyword
=> (:require {:abc 1 :require 14})
14
自分自身をマップで調べます。したがって、[clojure.set :as set]
をキーワードにすると、それはベクトルに評価しようとしますが、何を知っていないために失敗しますclojure.set
です。 Clojure docs と言う:
キーワードは、オプションの2番目の引数(デフォルト値)を持つ1つの引数(マップ)のinvoke()のIFnを実装します。たとえば、(:mykey my-hash-map:none)は(get my-hash-map:mykey:none)と同じ意味です。
ns
マクロ で混乱している可能性があります:
(ns foo.bar
(:refer-clojure :exclude [ancestors printf])
(:require (clojure.contrib sql sql.tests)) ;; here's :require!
(:use (my.lib this that))
(:import (Java.util Date Timer Random)
(Java.sql Connection Statement)))