Common Lisp
状態は、ベクトルにバインドされた特殊変数の数として定義します。そのため、特殊変数への割り当てにより状態が変更されます。
(defgeneric state (object)
(:documentation "Get the state of this object."))
(defmethod state ((object vector))
;; The state of a vector is the number of symbols bound to it.
(let ((count 0))
;; Iterate each SYM, return COUNT.
(do-all-symbols (sym count)
;; When SYM is bound to this vector, increment COUNT.
(when (and (boundp sym) (eq (symbol-value sym) object))
(incf count)))))
(defparameter *a* #(this is a vector))
(defparameter *b* nil)
(defparameter *c* nil)
(print (state *a*))
(setf *b* *a*)
(print (state *a*))
(print (state *a*))
(setf *c* *a*)
(print (state *a*))
出力:
1
2
2
3
これは、字句変数やオブジェクト内のスロットへの割り当てではなく、特殊変数への割り当てでのみ機能します。
do-all-symbols
すべてのパッケージを調べることに注意してください。したがって、パッケージを持たない変数を見逃します。複数のパッケージに存在するシンボルをダブルカウントする場合があります(あるパッケージが別のパッケージからシンボルをインポートした場合)。
ルビー
Rubyはほぼ同じですが、配列を参照する定数の数として状態を定義します。
class Array
# Get the state of this object.
def state
# The state of an array is the number of constants in modules
# where the constants refer to this array.
ObjectSpace.each_object(Module).inject(0) {|count, mod|
count + mod.constants(false).count {|sym|
begin
mod.const_get(sym, false).equal?(self)
rescue NameError
false
end
}
}
end
end
A = %i[this is an array]
puts A.state
B = A
puts A.state
puts A.state
C = A
puts A.state
出力:
state-assign.rb:9:in `const_get': Use RbConfig instead of obsolete and deprecated Config.
1
2
2
3
これは、クラスまたはモジュールではないRubyオブジェクトに対するhistorcratの答えの一般化です。警告が表示されるのは、Config定数が警告を行ったコードを自動ロードするためです。
LValue = obj
行が必要state
ですか?(取得するたびに増分するプロパティをC#で作成することもできます)