2014-11-26-01-lambdaでクラス - 3
>> Site top >> weblog >> 月別アーカイブ >> 2014年11月のlog >> 2014-11-26-01-lambdaでクラス - 3
最終更新日付:2014/11/26 01:00:00
lambdaでクラス - 3
2014 年 11 月 26 日
CL-CLASS というライブラリ、使い始めた途端におかしなところに気付く。なんとまぁ、コンストラクタの内部からパラメータにアクセスできないとな。
以下の非常に単純な例では、a と b にアクセスできない。
(class:define foo :constructors ((foo (a b) () (print (+ a b)))))
これは、現状では以下のように展開されるからだ。ダメだね。
(let () (cl-overload:declare-constructor foo (2)) (labels ((#:foo-class762 () (macrolet () (labels ((#:object756 (#:this757 #:optype758 &rest #:args759) (declare (ignorable #:this757 #:optype758 #:args759)) (ecase #:optype758 ((#:ctor-763) (let ((cl-class:this #:this757)) (declare (ignorable cl-class:this)) (print (+ a b))))))) #'#:object756)))) (cl-overload:defmethod-constructor foo (a b) (let* ((#:this757 (#:foo-class762))) (funcall #:this757 #:this757 '#:ctor-763) #:this757))))
なんでこんなことになっているかというと、コンストラクタの内部からクラスのメンバメソッドをコール可能でなければならないという必要性から、コンストラクタの実装部分をクロージャ内部に移動したのだった( 上記コードの #:ctor-763 というやつ )。しかし、その際にコンストラクタに渡されるパラメータへのアクセスを確保しなかったという顛末。嗚呼。
色々面倒なので詳細は省くけれども、とにかく以下のように展開されるようにした。これでコンストラクタ内部からメンバメソッドやデータメンバにもアクセスできるし、コンストラクタパラメータにもアクセスできるわけだ。
(let () (cl-overload:declare-constructor foo (2)) (labels ((#:foo-class801 () (macrolet () (labels ((#:object795 (#:this796 #:optype797 &rest #:args798) (declare (ignorable #:this796 #:optype797 #:args798)) (ecase #:optype797 ((#:ctor-802) (destructuring-bind (a b) #:args798 (let ((cl-class:this #:this796)) (declare (ignorable cl-class:this)) (print (+ a b)))))))) #'#:object795)))) (cl-overload:defmethod-constructor foo (a b) (let* ((#:this796 (#:foo-class801))) (funcall #:this796 #:this796 '#:ctor-802 a b) #:this796))))
コメント
このページのタグ
Page tag : Common Lisp
Copyright(C) 2005-2021 project-enigma.
Generated by CL-PREFAB.