Ruby 変数のインスタンス変数

アットマークのコーヒー

H&Sプロダクション/ゲッティイメージズ





インスタンス変数はアットマーク (@) で始まり、クラス メソッド内でのみ参照できます。特定の変数内に存在しないという点で、ローカル変数とは異なります。 範囲 .代わりに、クラスのインスタンスごとに同様の変数テーブルが格納されます。インスタンス変数はクラス インスタンス内に存在するため、そのインスタンスが存続している限り、インスタンス変数も存続します。

インスタンス変数は、そのクラスの任意のメソッドで参照できます。クラスのすべてのメソッドが同じインスタンスを使用する 変数テーブル 、各メソッドが異なる変数テーブルを持つローカル変数とは対照的です。ただし、最初にインスタンス変数を定義せずにインスタンス変数にアクセスすることは可能です。これは例外を発生させませんが、変数の値は なし でRubyを実行すると、警告が発行されます -の スイッチ。



この例は、インスタンス変数の使用を示しています。注意してください シバン を含む -の 警告が発生した場合に警告を出力します。また、クラス スコープ内のメソッド以外での誤った使用法にも注意してください。これは誤りであり、以下で説明します。

なぜ @テスト 変数が間違っていますか?これは、スコープと、Ruby が実装する方法に関係しています。メソッド内では、インスタンス変数のスコープはそのクラスの特定のインスタンスを参照します。ただし、クラス スコープ (クラス内ではあるがメソッドの外側) では、スコープは クラスインスタンス 範囲。 Ruby はインスタンス化によってクラス階層を実装します。 クラス オブジェクトなので、 2 番目のインスタンス ここで遊んでいます。最初 実例 のインスタンスです クラス クラス、そしてこれが場所です @テスト 行きます。 2 番目のインスタンスは、 テストクラス 、そしてここが @価値 行きます。これは少し混乱しますが、決して使用しないことを忘れないでください @インスタンス変数 メソッドの外。クラス全体のストレージが必要な場合は、 @@class_variables これは、クラス スコープのどこでも (メソッドの内外を問わず) 使用でき、同じように動作します。



アクセサー

通常、オブジェクトの外部からインスタンス変数にアクセスすることはできません。たとえば、上記の例では、単純に呼び出すことはできません。 t値 また t.@値 インスタンス変数にアクセスする @価値 .これはルールを破るだろう カプセル化 .これは子クラスのインスタンスにも当てはまります。技術的には同じ型であっても、親クラスに属するインスタンス変数にアクセスすることはできません。したがって、インスタンス変数へのアクセスを提供するには、 アクセサー メソッドを宣言する必要があります。

次の例は、アクセサー メソッドの記述方法を示しています。ただし、 ルビー はショートカットを提供し、この例はアクセサー メソッドがどのように機能するかを示すためにのみ存在することを示しています。アクセサーになんらかの追加ロジックが必要でない限り、一般に、この方法で書かれたアクセサー メソッドは一般的ではありません。

ショートカットを使用すると、物事が少し簡単になり、コンパクトになります。これらのヘルパー メソッドは 3 つあります。これらはクラス スコープ (クラス内でメソッドの外側) で実行する必要があり、上記の例で定義されたメソッドと同様にメソッドを動的に定義します。ここで魔法が起こっているわけではなく、言語のキーワードのように見えますが、実際にはメソッドを動的に定義しているだけです。また、これらのアクセサーは通常、クラスの先頭に配置されます。これにより、読者は、クラス外または子クラスで使用できるメンバー変数の概要を即座に把握できます。

これらのアクセサ メソッドは 3 つあります。それらはそれぞれ、アクセスするインスタンス変数を記述するシンボルのリストを取ります。



    attr_reader- などの「リーダー」メソッドを定義します。 名前 上記の例のメソッド。attr_writer- などの「ライター」メソッドを定義します。 年齢= 上記の例のメソッド。attr_accessor- 「リーダー」メソッドと「ライター」メソッドの両方を定義します。

インスタンス変数を使用する場合

インスタンス変数とは何かがわかったところで、いつそれらを使用しますか?インスタンス変数は、オブジェクトの状態を表すときに使用する必要があります。生徒の名前と年齢、成績など。一時的な保存には使用しないでください。ローカル変数はそのためのものです。ただし、多段階計算のメソッド呼び出し間の一時的なストレージとして使用できる可能性があります。ただし、これを行っている場合は、メソッドの構成を再考し、代わりにこれらの変数をメソッド パラメーターにすることをお勧めします。