Rubyのブロックのスコープって??

最近,仕事でRubyを使ってます。って使ってるのはオレだけだけど。Rubyを使ってデータまとめのためのスクリプトを作成してます。たまに,スクリプトを作るよりもコピペでやったほうが早いのでは?と感じるときもあるが,同じようなデータをまとめるときに楽なので良いのだ,と言い聞かせてスクリプトを書いてる。まあ,実際同じスクリプトを使う機会は多いのだけど。もちろん,スクリプトじゃなくちゃ無理なときもある。500MBのログからデータを抜き出してまとめるなんて無茶です。時間的にも,そして精神的にも。
今日も昨日に引き続き暇だったので,スクリプトを書くときに役立つであろうサブルーチンを書いていた。今までの経験から,扱うデータの特徴がわかってきたので,すべてを使い捨てにするのではなく幾分かは再利用しようと考えたのだ。
で,ここからが本題。Rubyのlambdaの仮引数(?)っておかしくないっすか?なんか直感に反するというか,なんというか。
例えば,

irb(main):001:0> x = 0
=> 0
irb(main):002:0> f = lambda {|a| a}
=> #<Proc:0x0005ae64@(irb):2>
irb(main):003:0> g = lambda {|x| x}
=> #<Proc:0x00057e6c@(irb):3>
irb(main):004:0> f.call(10)
=> 10
irb(main):005:0> x
=> 0
irb(main):006:0> g.call(10)
=> 10
irb(main):007:0> x
=> 10

fとgはアルファ同値(だっけ?)だから同じ処理かと思いきや,gの方は変数xに影響を与える。
調べてみると,どうやら『ダイナミックローカル変数』というやつが関わっているらしい。Rubyのブロックは外側のスコープの変数にアクセスできるので,{|x| x}のxも外側の変数xとして扱われ,仮引数xはブロック内で新たに定義されるわけではないらしい。仮引数も変数だと考えれば当然か。
しかし,これだと他のブロックを使う処理でも同じ問題がおこるな。

irb(main):008:0> e = 5
=> 5
irb(main):009:0> [1,2,3,4].each {|e| p e}
1
2
3
4
=> [1, 2, 3, 4]
irb(main):010:0> e
=> 4

むう,予想通りの結果だ。困った。今後はブロックを使うときにはちゃんと変数名を考えなくてはいかんなあ。というか,今までよく知らなくてスクリプト書けたな。||で挟まれた変数のスコープはブロック内だけだと思ってたから,いつも適当にeとかiを使ってたぞ。もしかしたら,今までのスクリプトも微妙に間違ってて,まとめたデータもおかしかったりして・・・*1
でもまあ,スコープ自体はレキシカルなので慣れればなんとかなるとは思う(たぶん)。

追加:Rubyのリファレンスにも似たような例がちゃんと載ってた。むう,whileやifがスコープをつくらないなんて知らなかった・・・。まあ,whileはあまり使わないし,if内で複雑な処理をやるようなスクリプトも書いてないから問題はないと思うが。

*1:もしそうだとしたらかなりヤバい