Edited at

Common LispでSingletonなクラスを作る(CLOS)

More than 1 year has passed since last update.


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

singleton.scm

Gaucheは使ったことないのでよくわからないけどスレッドセーフなSingletonが作れそう。