Dir.foreachループ内の変数のスコープがローカルなのはなぜですか?Dir.foreach()のローカルスコープRuby
私はファイルから必要な情報を見つけて変数と同じに設定するまでファイルをループしていましたが、ループの外側では変数を見ることができませんでした。私は今、グローバル変数を使用していますが、それはRubyで好まれないので、私はそれをする必要はありません。
Dir.foreachループ内の変数のスコープがローカルなのはなぜですか?Dir.foreach()のローカルスコープRuby
私はファイルから必要な情報を見つけて変数と同じに設定するまでファイルをループしていましたが、ループの外側では変数を見ることができませんでした。私は今、グローバル変数を使用していますが、それはRubyで好まれないので、私はそれをする必要はありません。
ブロック内に変数を設定した場合、以前に定義された変数が外側スコープにない限り、外側スコープからは使用できません。
「グローバル」とは最も外側のスコープを意味します。スコープの主な2つのレベル、メソッドとブロックがあります。いずれの場合も、同じ動作が表示されます。
a = 0
def foo
a = 1
b = 2
end
foo
a # => 1
b # => NameError
1.times do
a = 2
b = 3
end
a # => 2
b # => NameError
あなただけの一つの要素は、そうでなければ、あなたはそれだけではなく、外にそのブロックのスコープで定義されたブロック内の変数を定義する際にMaxpleは、言っfind
fname = Dir.foreach('.').find { |each| each =~ /store/i }
を使用する必要がある場合。変数を内側と外側の両方で使用する場合は、ブロックの前に変数を定義する必要があります。
しかし、前述のように、ほとんどの場合、代わりにEnumerable
モジュールの関数を使用できます。有用なものはselect
とfind
とmap
とany?
です。
ローカル変数は、定義されているスコープに対してローカルなので、結局、ローカル変数と呼ばれています。
Rubyには、スクリプト、モジュール/クラス定義、メソッド、ブロック/λリテラルの4つのローカル変数スコープがあります。これらの4つのうち、ブロックスコープのみが入れ子になり、ブロックのみがクロージャーになります。
したがって、ブロック内にローカル変数を定義すると、ローカル変数はそのブロックにローカルになります。しかし、ローカル変数をブロックの外側に定義すると、ブロックスコープが外側のスコープの内側にネストされるため、(ブロックローカル変数として明示的に宣言されている場合を除いて)ブロックで使用できるようになります。ブロックスコープは周囲のレキシカル環境で閉じるため、外部スコープが終了した後でブロック内で使用できるようになります。
注:たとえfor
/in
イテレータはこの特別場合には、ブロックは独自のスコープを取得していない、ブロックでeach
にメッセージにdesugar。回避するもう一つの理由for
/in
。
foo = :outerfoo
bar = :outerbar
[nil].each do |*; bar|
foo = :innerfoo
bar = :innerbar
baz = :innerbaz
end
foo #=> :innerfoo
bar #=> :outerbar
baz # NameError: undefined local variable or method `baz' for main:Object
for * in [nil]
looks_local_but_isnt = :huh
end
looks_local_but_isnt #=> :huh
ありがとうございます。私はそれまでにそれに遭遇したことがないことに驚いています。それが教訓であることを願っています。私は非常に頻繁にブロックをこのように使用しないか、他の何らかの理由で変数を宣言していると思います。今、私のグローバル変数はなくなりました。 – Greg