Ruby クラスの属性を理解し、アクセサー マクロと self を使用する
概要
そこで、Ruby でクラスを作成します。
class User
def initialize
end
end
ここで、ゲッター/セッターを使用してハッシュである属性を作成したいとします。これを行うためのオプションについて混乱しています。
これを行うと:
class User
attr_accessor :some_hash
end
しかし、このハッシュが nil になることは望ましくなく、常に空のハッシュになります。
いつやるべきか迷っています:
def some_hash
self.some_hash ||= {}
end
そして、やります:
def some_hash
@some_hash ||= {}
end
違いはなんですか?
attr_accessor を使用しない場合は、リーダーとライター (またはゲッター/セッター) の両方を作成する必要があります。
def some_hash=()
end
def some_hash
end
ハッシュである some_hash 属性を作成するためのオプションを誰かが明確にしてくれ、それが空の場合は決して nil を返さないことを願っています。
つまり、attr_accessor を使用し、メソッドを手動で作成し、最後に @some_hash と self.some_hash をいつ使用するかです。
解決策
attr_accessor :some_hash は、指定された属性のリーダーおよびライター メソッドを定義します。これは次と同等です。
class User
def some_hash
@some_hash
end
def some_hash=(a_hash)
@some_hash = a_hash
end
end
@some_hash はオブジェクトのインスタンス変数を参照し、some_hash と some_hash= はメソッドです。前者は変数の値を返し、後者は変数を設定します。
イディオム self.some_hash ||= {} は self.some_hash || と同等です。 self.some_hash = {}。
Ruby のブール演算子はショートサーキットです。つまり、最初の式 (self.some_hash) が true 値を返した場合、2 番目の式 (self.some_hash = {}) はまったく実行されません。
方法:
def some_hash
self.some_hash ||= {}
end
some_hash || に展開されるため、実際には再帰的です。 self.some_hash = {}。スタック オーバーフローが発生するまで、自身を呼び出し続けます。 2 番目の形式を使用します。
def some_hash
@some_hash ||= {}
end
インスタンス変数を直接設定するため、再帰の問題は発生せず、ライター メソッドを呼び出す必要もありません。 @some_hash が nil の場合、メソッドが戻る前に空のハッシュが割り当てられるため、some_hash は nil を返すことはできません。
ちなみに、変数は User インスタンスの作成時ではなく、最初にアクセスされたときに初期化されるため、これは遅延初期化とも呼ばれます。