Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyのインスタンス変数とは?初心者向けに基本から使い方までわかりやすく解説

Rubyのインスタンス変数について学びたいと思っているなら、この記事はまさにうってつけです。この記事では、インスタンス変数の仕組みや、なぜ便利なのかを順を追って解説していきます。

それでは、最初の質問から始めましょう。

インスタンス変数とは何か?

Rubyプログラミング言語におけるインスタンス変数とは、@記号で始まる種類の変数のことです。

:

@fruit

インスタンス変数は、オブジェクト指向プログラミング(OOP)において、オブジェクトそれぞれがデータを格納するための「自分専用のプライベートな領域」を持てるようにするために使われます。

オブジェクトには、次の2つの側面があると言われます。

  1. 動作すること(Do) — 何かを実行する
  2. 知識を持つこと(Know) — データを保持する

メソッドは物事を実際に実行します。つまり「DO」の役割です。

一方、インスタンス変数はデータを保存します。つまり「KNOW」の役割を担います。

:

Fruit(果物)クラスがある場合、「どんな種類の果物か」「色は何色か」「重さはどれくらいか」といった情報を知りたくなるでしょう。

これらの属性はすべて、インスタンス変数として表現されます。

たとえば @color@type@weight のような形です。

次に、具体的なコード例を見ていきましょう。

Rubyのインスタンス変数の定義方法と使い方

インスタンス変数は、クラスの中で定義します。

:

ここに CoffeeMachine(コーヒーマシン)クラスがあるとしましょう。

コーヒーマシンには水が必要なので、「タンクに水があとどれくらい残っているか」を知りたいはずです。

次のように書けます:

class CoffeeMachine
  def initialize
    @water = 100
  end
end

この @water がインスタンス変数です。initialize メソッド内で初期値として 100 を代入しています。

さらにmake_coffee メソッドを作れば、コーヒーを淹れるたびにタンク内の残り水量を減らすこともできます。

class CoffeeMachine
  def initialize
    @water = 100
  end

  def make_coffee
    @water -= 10
  end
end

注目すべき点は、new で生成した CoffeeMachine オブジェクトごとに、@water の値がそれぞれ独立して保持されるということです。

当然ですよね?

現実にコーヒーマシンが10台あれば、それぞれの水の残量は別々だからです。

これこそが、インスタンス変数を使う理由なのです。

インスタンス変数へのアクセス方法

現在の値を読み取れなければ、インスタンス変数はあまり役に立ちません。

インスタンス変数の値は、同じく @ 構文を使って読み取ることができます。

次のように書きます:

class CoffeeMachine
  def initialize
    @water = 50
  end

  def print_water_level
    puts "Water Level: #{@water}"
  end
end

machine = CoffeeMachine.new
machine.print_water_level

# Water Level: 50

print_water_level メソッドが @water を参照して、その値を出力しています。

アトリビュートアクセサ(attr_reader)を使う方法

ここで気づいたかもしれませんが、インスタンス変数はクラスの外部から直接アクセスできません

これは意図的な設計です!

これを「カプセル化(Encapsulation)」と呼びます。オブジェクトのデータが、他のRubyオブジェクトなど外部の世界から保護される仕組みです。

実際に試してみるとこうなります:

machine = CoffeeMachine.new

machine.water
# NoMethodError: undefined method `water' for #<CoffeeMachine:0x2d0a530>

machine.@water
# SyntaxError: unexpected tIVAR, expecting '('

ただし、場合によっては外部からのアクセスを許可したいこともあるでしょう。

その場合は、オブジェクトのデータに「窓」を開けて、外部から利用できるようにします。

ひとつ目の方法は、値を返すだけのメソッドを自前で定義することです。

class CoffeeMachine
  def initialize
    @water = 100
  end

  def water
    @water
  end
end

machine = CoffeeMachine.new
machine.water

# 100

特別なことは何もしていません。クラス内部(そこでは変数にアクセスできる)から値を返しているだけです。

ふたつ目の方法は、アトリビュートリーダー(attr_reader)を使うことです。

:

class CoffeeMachine
  attr_reader :water

  def initialize
    @water = 100
  end
end

machine = CoffeeMachine.new
machine.water

# 100

結果は先ほどとまったく同じです。唯一の違いは、Rubyが面倒な作業を代わりに行い、water メソッドを自動的に生成してくれるという点です。

覚えておきたいポイント

インスタンス変数について、トラブルを避けるために知っておくべき点がいくつかあります。

メモしておきましょう:

  • 未定義のインスタンス変数は、必ず nil を返す
  • インスタンス変数は initialize メソッド内で作成しなければならないわけではないが、初期値を与えるのは一般的にここで行う
  • instance_variable_get のような高度なアクセス手段もあるが、使用は避けるべき

ちなみに、オブジェクトが持つインスタンス変数の一覧を取得することもできます。

次のように使います:

machine.instance_variables
# [:@water]

デバッグの際などに役立つはずです 🙂

もうひとつ重要な点として、Railsではインスタンス変数(たとえば @books など)が、コントローラーとビューの間でデータを受け渡すために使われる、ということを知っておきましょう。

もちろん、Railsを使っていなくても、自分のクラスの中で通常どおりインスタンス変数を活用できます。

まとめ

この記事では、Rubyのインスタンス変数について学びました。@ 記号で始まる変数の一種で、クラスの中でデータを格納する場所を提供するために使われます。

ぜひここから実践してみてください。記事中のコード例を実際に動かしたり、自分自身のコードを書いて試したりすることで、理解がぐっと深まるはずです。

最後までお読みいただき、ありがとうございました。

  1. 今もなおInternet Explorerを愛用するあなたへ――IE 11を快適にする必読の高速化テクニック6選

    Internet Explorer(IE)は1995年の登場以来、長年にわたりWindowsに標準搭載されてきた歴史あるブラウザです。Windows 10の登場以降はMicrosoft Edgeへと役割を譲り、IE 11が最後のバージョンとなりました。それでも、シンプルで使いやすいインターフェースを理由にIEを使い続けるユーザーは少なくありません。※補足:IE 11のサポートは2022年6月に終了しています。セキュリティ面のリスクを考えると、可能であれば最新ブラウザへの移行をおすすめします。ただし「どうしてもIEを使いたい」という方は、以下の方法で動作を大幅に改善できます。最近、IEの動きが遅

  2. ソーシャルメディア最新事情:Twitter、Facebook、Snapchatの注目アップデート3選

    近年、テクノロジーの進化は目まぐるしいスピードで続いています。あらゆる技術は、より大きく、より優れたものへと進化していくことが期待されています。その中でも絶え間ないアップデートが求められるプラットフォームの一つが、ソーシャルネットワーキングサービス(SNS)です。各社はユーザーにより良い体験を提供すべく、機能を追加したり廃止したりと、日々努力を重ねています。ここでは、お気に入りのSNSが生み出した最新の興味深いトピックをいくつかご紹介します。1. Twitter、卵のアイコンに別れを告げるマイクロブログサービスのTwitter(現X)は、顔を見せたくないユーザーのデフォルト画像として長年使われ