Clojureはコードローディングと依存関係の追跡のための "lib" 機構を提供している。libとはクラスパス内のJavaリソースに存在する、単一の名前ついたClojureソースコードである。libは一般的に、一つのClojure名前空間の完全な定義を提供する。

libの規約

Clojureはlibの命名と構成における規約を定義している:

  • libの名前は通常ふたつ以上のピリオドで区切られたシンボルである。

  • libはJavaのリソースとして、libの名前から導出されたクラスパスに対して相対的なパスに格納される:

    • パスは文字列

    • lib名のピリオドはパスではスラッシュで置換される

    • lib名のハイフンはパスではアンダースコアで置換される

    • パスの拡張子には".class"、 ".clj"、 もしくは ".cljc"を使用することができる(以下の libのロード順 を参照)

  • libは以下を行う"ns"フォームで始まる:

    • libと同じ名前のClojure名前空間を作成する

    • Javaのクラス、Clojureのコア機構、他のlib等に対する依存関係を宣言する

Clojureは"ns"に対する呼び出しが例外なしで完了した場合、宣言された依存関係は満たされており、それらが提供する機能は使用可能であることを保証する。

libの例

単純なlib:

(ns com.my-company.clojure.examples.my-utils
  (:import java.util.Date)
  (:use [clojure.string :only (join)])
  (:require [clojure.java.io :as jio]))
  • ns フォームがlibの名前空間に名前を付けるとともに依存関係の宣言を行う。このlibは通常名前によって相対クラスパスのパスに存在するソースファイルに定義される: com/my_company/clojure/examples/my_utils.clj (ピリオドからスラッシュ、ハイフンからアンダースコアへの変換に注意)。

  • :import 句でこのlibが java.util.Date を使用していることを宣言し、このlibのコード内において非修飾名で使用することが可能になる。

  • :use 句は clojure.string ライブラリの join 関数のみに対するして依存関係を宣言している。このライブラリ中のコードでは join を非修飾名で使用することができる。

  • :require 句は clojure.java.io ライブラリ内の関数に対する依存関係を宣言し、それらを省略した名前空間エイリアス jio を使用して呼び出すことができる。

プレフィックスリスト

libが名前のプレフィックスを共有する複数のライブラリに依存することは一般的であり、 requireuse (および ns フォームにおける :require:use 句) に対する呼び出しにおいて共通のプレフィックスを取り出し、一度だけ指定することができる。例えば以下の2つのフォームは同義になる:

(require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql)
(require '(clojure.contrib def except sql))

関連する関数

名前空間の作成: ns

libがロードされたことを保証する: require use

ロードされたlibsの一覧: loaded-libs

libのロード順

libはコンパイル後 (.class) もしくはソース (.clj or .cljc) の形式で存在しうる。クラスパス上に一つ、もしくはそれら全てが存在する可能性があり、以下のルールでその中の一つからlibがロードされる:

  • .class ファイルはソースのタイムスタンプが .class のファイルより新しくない限り、常にソースファイルより優先される。ソースファイルのタイムスタンプの方が新しい場合はソースファイルが優先される。

  • 常に .clj (プラットフォーム特定のファイル) は常に .cljc より優先される(プラットフォーム間で共通)。

2つ目のルールは、ライブラリの作者がポータブルな共通の定義と、ホストプラットフォームを活かしたプラットフォーム固有の処理の上書きを同時に配布することを可能にする。