Common LispでSingletonなクラスをCLOSで書くとどうなるのか?
考えてみた結果以下のような感じになった。
singleton.lisp
(defpackage foo
(:use cl cl-user)
(:export foo
get-instance))
(in-package :foo)
;; fooクラスを定義する。
(defclass foo () ())
;; +instance+にインスタンスを格納。(この時点ではコンストラクタは呼び出し可能)
(defvar +instance+ (make-instance 'foo))
;; 新しいインスタンスを作れなくするためにコンストラクタを呼び出せないようにする
(defmethod initialize-instance :around ((this foo) &key)
(error "can't create instance."))
;; インスタンスを取得するための関数を作る。(defunで定義された関数をstaticなメソッドのように使う)
(defun get-instance ()
+instance+)
(in-package :cl-user)
なんだかすっきりしない形になった。
もっといい方法があれば教えてください。
追記(2017/8/19)
以下コメントで紹介していただいたものたち。
便利なものがありますね。
Common Lisp
cl-singleton-mixin
singleton-classes
どちらもQuickLispから利用できる。
Gauche
Gaucheは使ったことないのでよくわからないけどスレッドセーフなSingletonが作れそう。