5

clojure fn またはマクロの :arglist 属性を変更するにはどうすればよいですか?

(defn tripler ^{:arglists ([b])} [a] (* 3 a))

(defn ^{:arglists ([b])} quadrupler [a] (* 4 a))

% (meta #'tripler) => 
  {:arglists ([a]), :ns #<Namespace silly.testing>, :name tripler, :line 1, :file "NO_SOURCE_PATH"}

% (meta #'quadrupler) => 
  {:arglists ([a]), :ns #<Namespace silly.testing>, :name quadrupler, :line 1, :file "NO_SOURCE_PATH"}

わかりました、運が悪いので、次のことを試しました。

(def tripler
  (with-meta trippler
    (assoc (meta #'tripler) :arglists '([c]))))

% (with-meta #'tripler) => 
  {:ns #<Namespace silly.testing>, :name tripler, :line 1, :file "NO_SOURCE_PATH"}

うーん、それで :arglists キーはなくなりましたか? では、あきらめます。どうすればよいでしょうか。:arglists の値を変更したいだけです。上記の例では defn を使用していますが、マクロ (defmacro) を使用して :arglists を設定する方法も知りたいです。

4

4 に答える 4

3

アルターメタ!変数のメタデータを変更します。関数のメタデータは関係ありません。変数のみです。

(alter-meta! #'tripler assoc :arglists '([b]))
于 2012-09-20T21:09:38.133 に答える
2

defn はメタデータをマングルする余地を残しませんdef。defn の代わりに def を直接使用できます。

core> (def  ^{:arglists '([b])} tripler (fn [a] (* 3 a)))
#'core/tripler                                                                                 
core> (meta #'tripler)
{:arglists ([b]), :ns #<Namespace autotestbed.core>, :name tripler, :line 1, :file "NO_SOURCE_FILE"}

または、defn で var トリプラーを定義します。

core> (defn tripler [a] (* 3 a))
#'autotestbed.core/tripler                                                               

次に、同じ内容と異なるメタデータで var を再定義します。

core> (def ^{:arglists '([b])} tripler  tripler)
#'autotestbed.core/tripler                                                                                 
autotestbed.core> (meta #'tripler)
{:arglists ([b]), :ns #<Namespace autotestbed.core>, :name tripler, :line 1, :file "NO_SOURCE_FILE"}
于 2012-09-20T20:49:27.213 に答える
-1

amalloyの回答を拡張します(彼に信用を与えてください):

user=> (defn foo "prints bar" [] (println "bar"))
#'user/foo

user=> (doc foo)
-------------------------
user/foo
([])
  prints bar
nil

user=> (meta #'foo)
{:arglists ([]), :ns #<Namespace user>, :name foo, :doc "prints bar", :line 1, :file "NO_SOURCE_PATH"}

user=> (alter-meta! #'foo assoc :arglists '([blah]))
{:arglists ([blah]), :ns #<Namespace user>, :name foo, :doc "prints bar", :line 1, :file "NO_SOURCE_PATH"}

user=> (doc foo)
-------------------------
user/foo
([blah])
  prints bar
nil

user=> (meta #'foo)
{:arglists ([blah]), :ns #<Namespace user>, :name foo, :doc "prints bar", :line 1, :file "NO_SOURCE_PATH"}

user=> (foo)
bar
nil

こっそり!

于 2012-09-20T21:39:23.307 に答える