ローカル変数とインスタンス変数の違いを理解しよう

学習の目標

本章では、以下の内容を学習します。

  • ローカル変数とインスタンス変数の基本的な違いを理解する
  • それぞれの変数の特徴と使える範囲を学ぶ
  • それぞれの変数がいつまで値を保持するかを理解する
  • 実際のコードで適切に変数を使い分ける方法を身につける

はじめに

今回は、ローカル変数とインスタンス変数の違いと、それぞれの使い分けについて学んでいきます。

この2つの変数タイプは一見似ていますが、使える範囲といつまで値が残るかという点で大きく異なります。プログラミングにおいて、この違いを理解することは非常に重要です。

ファイルの準備

まずは、variable_scope.rbというファイルを作成しましょう。

VS Codeで新しいファイルを作成してください。これから、このファイルにクラスを定義していきます。

ローカル変数の特徴

ローカル変数の基本

ローカル変数は、その変数が定義されたメソッドやブロックの中だけで使える変数です。メソッドの処理が終わると、その中で定義したローカル変数は消えてしまいます。これは一時的な計算結果を保持するのに適しています。

class Calculator
def calculate_total(price)
tax = 0.1 # これはローカル変数
total = price * (1 + tax)
puts "税込金額:#{total}円"
end
def show_tax
puts "消費税:#{tax}" # エラーになります
end
end
calc = Calculator.new
calc.calculate_total(1000) # 税込金額:1100円と表示される
calc.show_tax # エラー:taxが未定義

このコードを実行すると、show_taxメソッドでtax変数にアクセスしようとした時点でエラーが発生します。なぜなら、ローカル変数taxcalculate_totalメソッドの中でしか使えないからです。

ローカル変数の命名規則

ローカル変数は必ず小文字またはアンダースコア(_)で始める必要があります。これはRubyの命名規則であり、Rubyはこの規則によって変数の種類を判別しています。

例えば、以下のような命名が可能です。

  • name
  • first_name
  • _temporary_value

ローカル変数の使える範囲

ローカル変数の使える範囲は、その変数が定義されたブロックやメソッド内に限定されます。別のメソッドや外部からはアクセスできません。

def method_a
local_var = "メソッドAの中の変数"
puts local_var # 正常に表示される
end
def method_b
puts local_var # エラー:local_varは定義されていない
end
method_a
method_b # エラーが発生

インスタンス変数の特徴

インスタンス変数の基本

インスタンス変数は、インスタンスが持つデータを保持するための変数です。クラスの中のどのメソッドからでも使えるという特徴があります。

class Calculator
def calculate_total(price)
@tax = 0.1 # これはインスタンス変数
total = price * (1 + @tax)
puts "税込金額:#{total}円"
end
def show_tax
puts "消費税:#{@tax}" # @taxを参照できます
end
end
calc = Calculator.new
calc.calculate_total(1000) # 税込金額:1100円と表示される
calc.show_tax # 消費税:0.1と表示される

このコードでは、インスタンス変数@taxcalculate_totalメソッドで設定し、別のshow_taxメソッドでも参照しています。これが可能なのは、インスタンス変数がインスタンス全体で共有されているためです。

インスタンス変数の命名規則

インスタンス変数は必ず@(アットマーク)で始まります。これがインスタンス変数の目印となり、Rubyは@から始まる変数をインスタンス変数として認識します。

例えば、以下のような命名が可能です。

  • @name
  • @first_name
  • @age

インスタンス変数の使える範囲

インスタンス変数の使える範囲はそのインスタンス内全体です。つまり、そのインスタンスのどのメソッドからも同じインスタンス変数にアクセスできます。ただし、別のインスタンスからは直接アクセスできません。各インスタンスは自分自身のインスタンス変数のセットを持っています。

class Person
def set_name(name)
@name = name
end
def greet
puts "こんにちは、#{@name}さん" # どのメソッドからでも@nameにアクセス可能
end
end
person1 = Person.new
person1.set_name("田中")
person1.greet # こんにちは、田中さん
person2 = Person.new
person2.set_name("佐藤")
person2.greet # こんにちは、佐藤さん
# person1と person2は別々の@name変数を持っています

値がいつまで残るかの違い

ローカル変数の値の保持期間

ローカル変数とインスタンス変数では、値がいつまで残るかも大きく異なります。

ローカル変数は、メソッドの呼び出しごとに新しく作られ、メソッドの終了とともに消えます。つまり、メソッドが終了すると、その中で定義されたローカル変数は値を失い、次にメソッドが呼び出されると再び初期化されます。

インスタンス変数の値の保持期間

一方、インスタンス変数は、そのインスタンスが存在する限り値を保持し続けます。メソッドの呼び出しが終わっても値は消えません。

class Counter
def count_up
count = 0 # ローカル変数
@number = 0 if @number.nil? # インスタンス変数(初回のみ0で初期化)
count += 1
@number += 1
puts "count: #{count}"
puts "number: #{@number}"
end
end
counter = Counter.new
counter.count_up # count: 1, number: 1と表示(両方とも最初は0から)
counter.count_up # count: 1, number: 2と表示(countは毎回リセット、numberは値を保持)
counter.count_up # count: 1, number: 3と表示

このコードを実行すると、ローカル変数countは毎回1になりますが、インスタンス変数@numberは呼び出すたびに増えていきます。これは、ローカル変数がメソッドの呼び出しごとにリセットされるのに対し、インスタンス変数はインスタンスが存在する限り値を保持し続けるためです。

使い分けの基準

基本的な使い分け

では、ローカル変数とインスタンス変数をどのように使い分ければよいのでしょうか。

基本的には、以下のように覚えておくと良いでしょう。

  • ローカル変数:メソッド内だけで完結する一時的な計算に使う
  • インスタンス変数:インスタンスの状態として保持しておきたい情報に使う

使い分けの実践例

実際のコードで見てみましょう。

class User
def format_name(first, last)
# メソッド内だけで使う一時的な変数はローカル変数で十分
full_name = "#{last} #{first}" # ここではローカル変数
puts full_name
end
def set_age(age)
# インスタンスが存在する間、値を保持したい場合はインスタンス変数
@age = age # 年齢は後からでも使いたいのでインスタンス変数
end
def show_age
puts "年齢:#{@age}歳" # 別のメソッドでも@ageを参照できる
end
def adult?
# @ageの値を使って判定
@age >= 20 # インスタンス変数は他のメソッドでも使える
end
end
user = User.new
user.set_age(25)
user.show_age # 25歳と表示
puts user.adult? # trueと表示

この例では、format_nameメソッド内で使うfull_nameはメソッド内だけで使われる一時的な変数なので、ローカル変数として定義しています。

一方、@ageはユーザーの年齢を表す重要な情報で、set_ageshow_ageadult?など複数のメソッドで使用するため、インスタンス変数として定義しています。

複数メソッド間での値の共有

インスタンス変数の主な利点は、複数のメソッド間で値を共有できることです。以下の例を見てみましょう。

class ShoppingCart
def initialize
@items = [] # 買い物カゴの中身を保持するインスタンス変数
end
def add_item(item)
@items.push(item)
puts "#{item}を買い物カゴに入れました"
end
def show_items
puts "買い物カゴの中身:"
@items.each { |item| puts "- #{item}" }
end
def total_items
@items.length
end
end
cart = ShoppingCart.new
cart.add_item("りんご")
cart.add_item("バナナ")
cart.show_items
puts "合計#{cart.total_items}個の商品があります"

この例では、買い物カゴの中身を表す@itemsをインスタンス変数として定義しています。これにより、add_itemshow_itemstotal_itemsの各メソッドで買い物カゴの情報を共有できます。

もしこれをローカル変数で実装しようとすると、メソッド間でデータを受け渡す必要があり、コードが複雑になってしまいます。

まとめ

今回は、ローカル変数とインスタンス変数の違いについて学びました。

ローカル変数は、定義されたメソッドの中だけで使える一時的な変数です。メソッドが終了すると値は消えます。メソッド内の一時的な計算や処理に適しています。

インスタンス変数は、インスタンスが存在する間ずっと値を保持し、クラスのどのメソッドからでも使えます。インスタンスの状態や性質を表すデータを保持するのに適しています。

一時的な処理にはローカル変数を、インスタンスの状態を表すデータにはインスタンス変数を使うのが基本です。

変数の種類を適切に使い分けることで、より読みやすく、メンテナンスしやすいプログラムを書くことができます。それぞれの特性を理解し、状況に応じて最適な変数タイプを選択しましょう。

このセクションは有料サブスクリプションへの登録、またはログインが必要です。完全なコンテンツにアクセスするには、料金ページ(/pricing)をご覧ください。購入済みの場合は、ログインしてください。

Starterプランでより詳しく学習

この先のコンテンツを読むにはStarterプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。

作成者:とまだ
Previous
インスタンス変数でデータを管理しよう