2016-06-23 13 views
1

クラス名を指定すると、nameインスタンス変数とそのアクセサーをフォームに自動的に作成する次のコードを試していますclassname-nameCLマクロ内で文字列からクラスアクセサー名を作成

(defmacro def-named-class (class-name) 
    `(defclass ,class-name() 
    ((name :accessor ,(intern (format nil "~A-~A" class-name "name")) 
      :initarg :name 
      :initform "")))) 

ここでの問題は、マクロの実行は、引数fooと言うとき、アクセサ関数の名前が|FOO-name|として来る、ということですが、私はそれだけでfoo-nameになりたいです。理由は、(intern "foo-name")はシンボル|foo-name|を返します。

(defmacro def-hyp (name1 name2 arg-list &body body) 
    `(defun ,(intern (format nil "~A-~A" name1 name2)) 
      ,arg-list 
      ,@body)) 

そしてそれは正しく名前foo-nameと機能を生成(def-hyp foo name() 'foo-name)のようにそれを呼び出します。しかし、私はこのように、正常な機能を同じことをしようとした場合。だから私は最初のマクロ内の文字列表現から正確に同じシンボルを取得する方法があるのだろうかと思います。私はClozure CLを使用しています。

+5

[1関数名に2つの変数を組み合わせることに答えを行いますマクロで](http://stackoverflow.com/questions/24433035/combining-two-variables-into-one-function-name-in-macro)あなたのためにこれを解決する?受け入れられた回答の形式に関する部分に特に注意してください(免責事項:それは私のものです)。 –

答えて

1

あなたが大文字に名を変換する必要があります。

(defmacro def-named-class (class-name) 
    `(defclass ,class-name() 
    ((name :accessor ,(intern (format nil "~A-~A" (string-upcase class-name) "NAME")) 
      :initarg :name 
      :initform "")))) 

別の可能性、jkiiskiによってコメントで提案されているように、唯一のフォーマット文字列を変更することです:

... 
((name :accessor ,(intern (format nil "~:@(~A-~A~)" class-name "name")) 
... 

理由はということですCommon Lispリーダーのデフォルトの動作は、それを読む際に大文字のシンボルを変換することです。したがって、foo-nameと書くと、自動的にFOO-NAMEに変換されます。取得するには、(intern "FOO-NAME")を使用してください。ただし、必要に応じて、リーダーのデフォルトの動作を変更することができます(manualを参照)。

+0

それはうまくいった、ありがとう。しかし、なぜ私は2番目のケースで正常な関数の場合、適切な名前を作成することができたのだろうと思っています。 –

+1

@ sourav.dという理由から、シンボルは新しい名前( 'name1'と' name2'の値)を形成するために使用されるため、リーダによって自動的に大文字に変換されます。 – Renzo

+0

とにかく ''〜:@(〜A〜〜A〜) ''を使ってupcaseに変換することもできます。 – jkiiski

3

クラスにはすでに名前があります。

CL-USER 19 > (defclass foo()()) 
#<STANDARD-CLASS FOO 415040BE6B> 

CL-USER 20 > (class-name *) 
FOO 
2

継承によってうまく解決されませんか?

(defclass named() 
    ((name :initarg :name :accessor name-of))) 

...そしてあなたが名前を持つオブジェクトを定義する他のすべてのクラスのためにそれを使用することができます:ここにあなたのミックスインである

(defclass this (named) ...) 
(defclass that (named) ...) 
+0

はい、もちろんそれを行うより良い方法です。マクロは単なる実験に過ぎませんでした。 –

関連する問題