2017-03-01 4 views
0

私はRubyで可変スコープに苦労しています。私は、ローカル変数がその下のメソッドによってアクセス可能であったという印象を受けました。次のコードを見て、私は未定義の変数エラーが表示されます。Rubyのローカル変数のスコープ

a = Array.new 

def testing() 
    a.push("test") 
end 

testing 

グローバル変数を使用すると、正常に動作します。グローバル変数の使用を避けるにはどうすればよいですか?

答えて

4

Rubyのローカル変数は、定義されているスコープとそのスコープ内で定義されたブロック(クロージャ)でしかアクセスできないという点を除いて、ここではあまり言及しません。 Rubyでは、他の動的言語とは異なり、メソッドはクロージャではないため、ローカル変数を取得しません。

は、あなたがしようとした場合、と言うこの:

irb(main):001:0> a = 3 
=> 3 
irb(main):002:0> define_method(:testing) do 
irb(main):003:1* puts a 
irb(main):004:1> end 
=> :testing 
irb(main):005:0> testing 
3 

コードではなく、メソッドのブロックであるので、それは、動作します。

0

インスタンス変数を使用できます。名前が@で始まる変数はインスタンス変数であり、定義されているクラスまたはメソッドのどこでも使用できます。たとえば、クラスB内で定義された変数@AはB.

のいずれかの方法に利用できるようになります
0
2.3.3 :007 > def testing() 
2.3.3 :008?> [].push("test") 
2.3.3 :009?> end 
=> :testing 
2.3.3 :010 > testing 
=> ["test"] 

あなたはその下の方法でローカル変数にアクセス任せることはできない、あなたは@Linuxiosによって答えのようなブロックを使用することができます、またはそれが簡単に働く方法を使用してください。

1

top-levelのメソッドを定義することはかなり混乱する可能性があります。のではなく、クラスで自分のコードをラップしてみましょう:このdoesnの、どうやら

foo = Foo.new 
foo.testing 
#=> undefined local variable or method `a' 

class Foo 
    a = [] 

    def testing 
    a << 'test' 
    end 
end 

(私はa << ...[]a.push(...)Array.newを短縮しました)

Foo#testingを経由して呼び出すことができます仕事はありません。最初のaclassの範囲内のローカル変数ですが、2番目のaはインスタンスメソッド内のローカル変数です。ローカル変数はメソッド間で共有されていないため、

initializeメソッドにクラス本体の外に変数の初期化を移動すると、いずれかの動作しません:

class Foo 
    def initialize 
    a = []   # <- one 'a' 
    end 

    def testing 
    a << 'test' # <- another 'a' 
    end 
end 

この作業を取得するには、を使用する必要がありますインスタンス変数

class Foo 
    def initialize 
    @a = [] 
    end 

    def testing 
    @a << 'test' 
    end 
end 

foo = Foo.new 
foo.testing 
#=> ["test"] 

foo.testing 
#=> ["test", "test"] 
関連する問題