1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

Rubyのオブジェクト指向プログラミングにおけるスコープの簡単な説明

2022-01-31 12:49:46

スコープ

Rubyのスコープは切り捨てられ、新しいスコープに入ると、元のバインディングは新しいバインディングのセットに置き換えられます。

プログラムは前のスコープを閉じ、新しいスコープを開くが、その場所は次の3箇所である。

  • クラス定義クラス
  • モジュール定義モジュール
  • メソッド定義 def

上記の3つのキーワードは、それぞれスコープのドア(入口)に対応し、対応する末尾はそのドアから出ることに対応する。

スコープを平坦化する

ローカル変数は、あるスコープから別のスコープに移動すると即座に無効化されます。ローカル変数を持続させるには、キーワードを回避して、スコープゲートの代わりにメソッドコールを使用し、あるスコープから別のスコープの変数を参照できるようにすることで実現できます。これは、class を Class.new に、Module#define_method を def に、Module.new を module に置き換えることで実現できます。この方法はフラットスコープと呼ばれ、2つのスコープを一緒に押し込んでしまうことを意味します。

コード例 (誤)

my_var = "Success"
class MyClass
  puts my_var # "Success" does not print correctly here
  def my_method
    puts my_var # "Success" doesn't print correctly here
  end
end


サンプルコード(右)

my_var = "Success"
MyClass = Class.new do
  puts "#{my_var} in the class definition"
  define_method :my_method do
    "#{my_var} in the method"
  end
end



javaやC#などの一部の言語では、インナースコープという概念があります。アウタースコープにある変数をインナースコープで見ることができるのだ。しかし、rubyにはそのようなスコープの入れ子という概念はない。そのスコープは別々で、新しいスコープに入ると、元のバインディングは新しいバインディングの集合に置き換えられる。

rubyでは、クラス定義、モジュール定義、メソッドの3か所で、プログラムは前のスコープを閉じ、新しいスコープを開く。

スコープの切り替えは、プログラムがクラス、モジュール、メソッドの定義に入るたびに発生します。この3つの境界は、それぞれclass、module、defキーワードで示され、それぞれがスコープゲートとして機能する。

バインディングがスコープゲートを通過するためにはどうしたらよいのでしょうか。たとえば、次のようなコードです。

my_var = "hello"
class MyClass
     # You want my_var to be printed here
     def my_method
          #... And here
     end
end


ローカル変数は他のスコープに入ると即座に無効となります。class キーワードをスコープゲートでないもの、例えばメソッドに置き換えると、クロージャで my_var の値を取得し、そのクロージャをメソッドに渡すことができます。コードはこのようになります。

my_var = "hello"
MyClass = Class.new do
     puts "#{my_var} in the class definition"
     def my_method
          #... How do you print it out here?
     end
end


def の代わりに、Module#define_method() メソッドを使用し、以下のコードを記述します。

my_var = "hello"
MyClass = Class.new do
     puts "#{my_var} in the class definition"
     define_method :my_method do
          puts "#{my_var} in the method"
     end
end


 
MyClass.new.my_method



hello in the class definition
hello in the method



スコープゲートの代わりにメソッドを使用することで、あるスコープから別のスコープの変数を参照することができます。

スコープの共有

変数のフラットスコープに一連のメソッドを定義すると、その変数は限られた数のメソッドによってのみ共有されるようになります。これを共有スコープと呼びます。