Posted 2020-12-20 17:40:41 GMT
allocate-instance Advent Calendar 2020 21日目の記事です。
ネタ切れも甚しいのでallocate-instance
が関係してくるInstance Structure Protocol(ISP)周りを中心に色々なCLOS MOP系の処理系で確認していきたいと思います。
まずは、本家Common Lispです。
slot-exists-p
slot-boundp
slot-boundp-using-class
slot-makunbound
slot-makunbound-using-class
slot-value
slot-value-using-class
(setf slot-value)
(setf slot-value-using-class)
compute-slots :around
slot-definition-location
standard-instance-access
funcallable-standard-class
funcallable-standard-instance-access
ISPで列挙されているのは、スロットアクセス系の関数/メソッドになり、allocate-instance
等は埒外です。
ます、関係してくる順序としては、スロットストレージの並び順がcompute-slots :around
で確定し、インスタンスのストレージとスロットの位置が確定します。それに伴なって、slot-definition-location
の値も決まり、standard-instance-access
でのアクセスの添字も決まる、という感じです。
slot-value
の下請けが、slot-value-using-class
で、更に下請けが、standard-instance-access
とされていますが、処理系によっては、slot-value
からインスタンスのストレージに直通の場合もあるようです(LispWorksでスロットアクセスの最適化が有効になっている場合など)
standard-instance-access
は、インスタンスのストレージに添字でアクセスする低レベルの関数ですが、standard-
と付いていることから判るように、standard-object
を想定しています。
standard-object
とはインスタンスのストレージ構成が違う場合には使えないと考えた方が良いでしょう。
class-finalized-p
finalize-inheritance
継承関係の確定のプロトコルですが、インスタンスがアロケートされる前に確定している必要があるとされており、allocate-instance
が呼ばれる前にclass-finalized-p
で調べて確定していなければ、finalize-inheritance
が呼ばれるとされています。
この判定のタイミングですが、Robert Strandh先生によれば、allocate-instance
の引数のinitargs
は確定後の計算結果になるので呼ばれる前に確定している筈としていてPCLでも、make-instance
がfinalize-inheritance
を呼んでいると註記していますが、PCL系であるSBCL等では、allocate-instance
の中で呼ばれています(ensure-class-finalized
経由)。
大抵の処理系では、finalize-inheritance
を呼んでいるので、実際のところ必須なのかそうでないのか。ちなみに自分はStrandh先生を信じて今回のアドベントカレンダでは呼ばないスタイルで通しました。
make-instance
shared-initialize
change-class
update-instance-for-different-class
update-instance-for-redefined-class
あたりですが、インスタンスストレージの構成が標準と異なる場合は、初期化/再初期化の手続を別途記述する必要が出てきます。
また、標準的な構成とカスタマイズしたものとでchange-class
する場合は、インスタンスストレージの確保も別途記述する必要も出てきます。
大抵は、上記メソッドと標準メソッドコンビネーションでどうにかできますが、もしかしたら、標準から外れる場合は、Dependent maintenance protocolでストレージ形式の修正をしたりした方が良いのかもしれません。
関係プロトコルをざっと眺めてみましたが、allocate-instance
をカスタマイズする例がほとんどないですね。
思えば、allocate-instance
のカスタマイズは、大抵は初期の文献に見付かるのですが何故なのか(共通仕様をまとめるのが難しいとか?)
■
HTML generated by 3bmd in LispWorks 7.0.0