3

clojure のソース コードに取り組んでいると、何度もタイプ(ns user)したり押したりしていることに気付くことがよくあります。C+c M+n問題は、私が頻繁に and のような関数を使用sourcedocていて、それらが入っていて、名前空間clojure.replに入れたくないことです。:requireこの場合、経験豊富なクロジュリアンは何をしていますか?

明確化:私は clojure の名前空間がどのように機能するかを知っています。私が達成したいのは、REPL で完全修飾名を使用したり、各名前空間から関数を要求したりする必要なく、など呼び出すこと(source myfunc)ができるようにすることです。(doc myfunc)clojure.repl

4

2 に答える 2

4

求めていたものを解決してくれてありがとう。

Leiningen には:injectionsと呼ばれる機能があり、vinyasaと組み合わせてこの効果を得ることができます。

~/lein/profiles.clj:

{:user {:plugins []
        :dependencies [[im.chit/vinyasa "0.1.8"]]
        :injections [(require 'vinyasa.inject)
                      (vinyasa.inject/inject
                       'clojure.core '>
                       '[[clojure.repl doc source]
                         [clojure.pprint pprint pp]])]}}

これは profile.clj にあるため、影響を受けるのはあなただけです。プロジェクトで作業する他の人は影響を受けません。


clojure.core にインジェクトするのは少し難しいと思うので、vinyasa の作者のアドバイスに従い、 という名前の名前空間にインジェクトします。これは、私が取り組んでいるすべてのプロジェクトのプロファイルによって作成されます。この名前空間は常に存在するため、これらの関数は、まだ clojure.core を参照していない新しく作成された名前空間でも機能します。

私の ~/.lein/profiles.clj:

{:user
  {:plugins []
   :dependencies [[spyscope "0.1.4"]
                  [org.clojure/tools.namespace "0.2.4"]
                  [io.aviso/pretty "0.1.8"]
                  [im.chit/vinyasa "0.4.7"]]
   :injections
   [(require 'spyscope.core)
    (require '[vinyasa.inject :as inject])
    (require 'io.aviso.repl)
    (inject/in ;; the default injected namespace is `.`

               ;; note that `:refer, :all and :exclude can be used
               [vinyasa.inject :refer [inject [in inject-in]]]
               [clojure.pprint :refer [pprint]]
               [clojure.java.shell :refer [sh]]
               [clojure.repl :refer [doc source]]
               [vinyasa.maven pull]
               [vinyasa.reflection .> .? .* .% .%> .& .>ns .>var])]}}

次のように機能します。

hello.core> (./doc first)
-------------------------
clojure.core/first
([coll])
  Returns the first item in the collection. Calls seq on its
    argument. If coll is nil, returns nil.
nil
hello.core> (in-ns 'new-namespace)
#namespace[new-namespace]
new-namespace> (./doc first)
nil
new-namespace> (clojure.core/refer-clojure)
nil
new-namespace> (./doc first)
-------------------------
clojure.core/first
([coll])
  Returns the first item in the collection. Calls seq on its
    argument. If coll is nil, returns nil.
nil
于 2016-07-07T18:48:03.530 に答える
1

これを実現するには、vinyasaライブラリ、特にそのinject機能を使用できます。clojure.repl基本的に、名前空間から名前空間に必要な関数を追加する必要がありclojure.coreます。それらを明示的に要求する必要はありません。以下を参照してください。

user> (require '[vinyasa.inject :refer [inject]])
nil

;; injecting `source` and `doc` symbols to clojure.core
user> (inject '[clojure.core [clojure.repl source doc]]) 
[]

;; switching to some other namespace
user> (require 'my-project.core)
nil
user> (in-ns 'my-project.core)
#namespace[my-project.core]

;; now those functions are accessible w/o qualifier
my-project.core> (doc vector) 
-------------------------
clojure.core/vector
([] [a] [a b] [a b c] [a b c d] [a b c d e] [a b c d e f] [a b c d e f & args])
  Creates a new vector containing the args.
nil
于 2016-07-07T19:45:40.740 に答える