1. ホーム
  2. ruby

[解決済み] Rubyのローカル変数が未定義である

2022-01-28 10:26:26

質問

以下のようなRubyのコードを持っています。

local_var = "Hello"

def hello
  puts local_var
end

hello

以下のようなエラーが発生します。

local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' 
for main:Object (NameError) from local_variables.rb:7:in '<main>'

ローカル変数は、ブロック、関数、クロージャなどの外からアクセスできないものだとばかり思っていました。

しかし、今、私はファイル内でローカル変数を定義し、関数からアクセスを取得しようとしました。 INSIDE を実行すると、同じファイルが作成されます。

私の理解は間違っているのでしょうか?

どうすればいいですか?

Rubyのローカル変数は、その変数が定義されているスコープでのみアクセス可能です。クラスやモジュール、メソッドの定義に入ったり出たりするたびに、Ruby ではスコープが変わります。

例えば、以下のような場合です。

v1 = 1

class MyClass # SCOPE GATE: entering class
  v2 = 2
  local_variables # => ["v2"]

  def my_method # SCOPE GATE: entering def
    v3 = 3
    local_variables  # => ["v3"]
  end # SCOPE GATE: leaving def

  local_variables # => ["v2"]
end # SCOPE GATE: leaving class

この出入りするポイントをスコープゲートと呼ぶ。メソッド定義によってスコープ・ゲートから入るので、自分の local_var 内部 hello メソッドを使用します。


スコープ・フラット化の概念を利用して、変数をこれらのゲートに通過させることができます。

例えば def を使ってメソッドを定義することができます。 Module#define_method .

local_var = "Hello"

define_method :hello do
  puts local_var
end

同じように、クラスも Class#New というように、クラス定義を通過しても、スコープが変わらないようにします。

local_var = 'test'

MyClass = Class.new do
  puts local_var #valid
end

ではなく

class MyClass
  puts local_var #invalid
end

同じように Module#New は、モジュールゲートを介してローカル変数を渡したい場合。

この例は メタプログラミング Ruby