4

明らかに、外部から見えるAPIは、シンボルをエクスポートすることによって公開されます。しかし...複数のパッケージ(たとえば、A、B、C)があり、Aのエクスポートされたシンボルがすべて外部APIの一部であるとは限らない場合はどうなりますか?それらの一部はBとCに必要です。(同様に、BはAとCの一部のシンボルをエクスポートし、一部は外部APIのシンボルをエクスポートします。Cは「トップレベル」パッケージであり、エクスポートされたすべてのシンボルはパブリックAPIの一部です。モジュール化を維持し、Aが内部を非表示にできるようにします。 BとCからなので、「::」は避けます。

今の私の解決策は、Cから公開することを意図したものをすべて再エクスポートし、公開APIはCのエクスポートされたシンボルのみで構成されていることを文書化することです。バグやコードが壊れた場合は、AとBの公開シンボルに近づかないでください。内部インターフェースが変わる未来。

もっと良い方法はありますか?

更新:これは、Xachの答えに対する私の理解の実装です:

まず、私の例を完成させましょう。symbol-a-1シンボルとsymbol-a-2パッケージa、シンボルsymbol-b-1symbol-b-2パッケージbとシンボルapi-symbol-1、およびapi-symbol-2パッケージからエクスポートしたいc。からエクスポートされたシンボルのみがcパブリックAPIの一部です。

まず、a:の定義

(defpackage #:a
  (:use #:cl))

エクスポートされたシンボルがないことに注意してください:-)

ヘルパーマクロ(Alexandriaを使用):

(defmacro privately-export (package-name &body symbols)
  `(eval-when (:compile-toplevel :load-toplevel :execute)
     (defun ,(alexandria:format-symbol *package*
                                       "IMPORT-FROM-~a"
                                       (symbol-name package-name)) ()
       (list :import-from
             ,package-name
             ,@(mapcar (lambda (to-intern)
                         `',(intern (symbol-name to-intern) package-name))
                       symbols)))))

マクロを使用して「プライベートにエクスポート」:-):

(privately-export :a :symbol-a-1 :symbol-a-2)

今の定義b

(defpackage #:b
  (:use #:cl)
  #.(import-from-a))

... b's'エクスポート':

(privately-export :b :symbol-b-1 :symbol-b-2)

...cの定義:

(defpackage #:c
  (:use #:cl)
  #.(import-from-a)
  #.(import-from-b)
  (:export :api-symbol-1 :api-symbol-2)

このアプローチの問題点:

  • aからのシンボルを使用することはできませんb(両方が定義された後からのimportシンボルを使用せずに)。ba
  • 構文package:symbolは基本的に、「プライベートに」エクスポートされたシンボルには使用できません(またはのいずれかですsymbolpackage::symbol
4

3 に答える 3

2

:import-fromAとBが主にCの実装用である場合、外部ではないものをインポートできるため、Cのdefpackageフォームでを選択的に使用して物を駆動することができます。次に、そこから選択的に再エクスポートできます。

于 2012-10-18T12:46:37.967 に答える
1

すべてのパブリックAPIシンボルをエクスポートする3番目のパッケージDを追加し、A、B、およびCパッケージをプライベートと見なすことができます。次に、次のような修飾名を使用して、APIパッケージ内の関数と変数のすべての定義を修飾できます。

(defun D:blah () ...)

パブリックエントリポイントの定義を視覚的に簡単に見つけられるようにするため。

于 2012-10-18T09:06:43.133 に答える
1

おそらく、最も簡単な方法はハンスによって提案されています。

ティムブラッドショーのコンジットパッケージもご覧ください。

于 2012-10-18T12:18:04.223 に答える