PersistentObject
ORM から取り出されたと考えることができるオブジェクトがあります。これは、プログラミング言語でネイティブに使用できるオブジェクトであり (バックエンドには依存しません)、データベースに変更をコミットするためのメソッドload
とメソッドがあります。save
PersistentObject
つまり、サーバーがデータベース内のオブジェクトを参照するためだけに軽量ポインターとして初期化できるようにしたいのです。そして、その瞬間が来たら、実際にデータベースにアクセスしてフェッチすることで、メモリにフォールトできます。ここでのポイントは、オブジェクトをフェッチする必要なく、このオブジェクトを参照としてコレクションに追加できるようにすることです。また、従来のコンストラクターを使用して昔ながらの方法でオブジェクトを初期化し、データベースにコミットできるようにしたいと考えています (これは、既存のオブジェクトを操作するのではなく、新しいオブジェクトを最初から作成する必要がある場合に便利です)。
したがって、複数のコンストラクターを持つオブジェクトがあります。従来のコンストラクターと、データベース内のオブジェクト GUID に基づいて障害を作成するコンストラクターです。また、オブジェクトがフォールトとして初期化されると、インスタンス メソッドがインスタンス変数としてその状態にアクセスできるようにする必要があります。フォールトでの操作は、完全に読み込まれたオブジェクトでの操作とは異なるためです。しかし、明らかな理由から、クライアントに私の内部状態をいじらせたくないので、ivar のアクセサーを作成したくありません。私の質問は、オブジェクトインスタンスのクラスメソッドからivarを初期化/設定して、クラスの外部クライアントがそれを台無しにできないようにする(つまり、その値を別のものに設定する)ことです?
すべての言葉で申し訳ありませんが、コードはそれをより明確にする必要があります。明らかに機能しないものを試しましたが、ポイントをうまく説明しています。これが初歩的な質問である場合はお詫びします。私はRubyにまったく慣れていません。
class PersistentObject
def initialize(opts={})
@id = opts[:id] || new_id
@data = opts[:data] || nil
end
def self.new_fault(id)
new_object = PersistentObject.new
new_object.@fault = true #<----- How do you achieve this?
new_object
end
def new_id
#returns a new globally unique id
end
def fault?
@fault
end
def load
if fault?
#fault in the object from the database by fetching the record corresponding to the id
@fault = false
end
end
def save
#save the object to the database
end
end
#I create a new object as a fault, I can add it to collections, refer to it all I want, etc., but I can't access it's data, I just have a lightweight pointer which can be created without ever hitting the database
o = PersistentObject.new_fault("123")
#Now let's suppose I need the object's data, so I'll load it
o.load
#Now I can use the object, change it's data, etc.
p o.data
o.data = "foo"
#And when I'm ready I can save it back to the database
o.save
編集:クラスメソッドからそのインスタンスのivarにアクセスすることに私の心は設定されていないと言わなければなりません。この問題を解決するための慣用的なRubyパターンを聞いてうれしいです。