インスタンス変数の内容を楽に特異アクセサに渡す方法を考えた
Miyakoでゲーム作る作ると言っておきながら、全く実例が無いのは問題なので(ゲーム業界への転職も考えていますので、その点も含めて)、
システム部分を作ってしまおうと考えています。
前の日記で書いたノベルゲーム作成のために、ゲームエンジンを含んだシステムの構築をやっています。
そこで手に入れた知識をメモ。
インスタンスのコンポーネントを特異アクセサへ反映
まず、ノベルゲームを作ると言うことで、背景画面やBGM、メッセージボックスなど(ここではまとめて「コンポーネント」と呼びます)を
管理して、ゲームエンジンから参照できる様にしたいと考えています。そこで、管理クラスComponentsを作って、シーンごとにインスタンス変数を
作ってゲームエンジンがアクセス・・・うーん、ゲームエンジンはSingletonなので、インスタンスを作るよりも、特異アクセサのほうが
いいかもしんない。
つまり、「シーンごとに管理インスタンスは持つけど、シーンの始めに、コンポーネントを特異アクセサでアクセスできるようにコピーする」ことを
やってみようと考えています。
さて実装というところで、最初の問題が。
ここまでお話ししたことを考えると、インスタンスアクセサと特異アクセサの構成が共通していることになります。ならば、メソッド名の配列を
一気にattr_accesorの引数に渡したら簡単というわけで・・・attr_accesorはプライベートメソッドだから、特異アクセサではどうするんだ???
・・・と思ってたら、答えが「プログラミング言語Ruby」に書かれていました。持ってて良かった〜。
METHODS = [:hoge, :fuga] class << self attr_accessor *METHODS end
ただ、このアクセサでアクセスできるのは「クラス変数」ではなくて「クラスインスタンス変数」なので、インスタンスメソッドで参照するときは、
def func return A.hoge end
とすることを忘れない様に。
インスタンスのコンポーネントを特異アクセサでアクセスできる様に実装
続けて、インスタンスの内容をクラスインスタンスにコピーする方法。
まず注意する必要があるのは、「インスタンスアクセサと特異アクセサの内容は独立」という条件を付けています。インスタンスの内容を変えても、
特異アクセサの結果は変わらないようにしなければなりません。
というわけで、メソッドto_commonを以下のように実装致しました。
# encoding: UTF-8 # attrメソッドはクラス変数アクセスでも可能か? class A METHODS = [:hoge, :fuga] class << self attr_accessor *METHODS end attr_accessor *METHODS def to_common METHODS.each{|name| A.__send__(name.to_s+"=", self.__send__(name)) } end end a = A.new a.hoge = 15 a.fuga = 20 x = a.to_common a.hoge = 30 a.fuga = 40 puts A.hoge # => 15 puts A.fuga # => 20
いちいち文字列に変換して書き込みアクセサ名の文字列を作らなきゃならないのが不満ですが・・・。
こんな感じで実装していきます。
P.S.
"A.__send__(name.to_s+"=", self.__send__(name))"がイマイチ気に入らないけどなぁ・・・。